钜形不锈钢水箱 发表于 2024-8-31 06:20:27

Android 15新特性,强制edge-to-edge全面屏体验

本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每个工作日都有文章更新。
大家好,今天原创。
Android 15再过不了多久就要正式发布了,我也是第一时间就去了解了本年新体系的一些变革。
怎么说呢?之前我们一直吐槽Android技能变革过快,新学的很多知识没过多久就废弃了,再加上Google又不停地推出更新的技能,搞得开发者经常直呼学不动了。。
而现在大家不用再担心这个问题了,因为Android 15可以说是一个非常小的版本更新,并没有太多非常亮眼的点拿出来先容。
本年的Google I/O我也是观看了一遍,可以说现在AI成了Google唯一的核心,Android已经登不了Google I/O的大舞台了,只能在一个小房间来先容先容Android 15的新特性。
Android技能慢了下来,热度也降了下来,是喜是忧,大家冷暖自知。
关于本年Android 15新特性的文章,我把重要的行为变动过了好几遍,感觉非常值得一讲的也就是强制edge-to-edge全面屏体验这项变革了。这项变革内容很简单,但是由于可能会影响到全部的Android应用,所以还是发起大家学习了解一下。
其实edge-to-edge全面屏体验并不是什么全新的功能,早在Android 15之前就已经支持了。
但是这个功能推出了很多年,仍旧有大量的应用程序没有对全面屏体验举行适配。所以,在这次的Android 15更新中,Google终于下决心要强推这个功能,以让全部应用程序都能达到更好的体验。
需要阐明的是,只有将App的targetSdkVersion指定到35或更高时,Android 15才会强制启用edge-to-edge功能。所以,如果你就是不想适配,那么只要不升级targetSdkVersion的版本就行了。
下面开始进入正题,起首跟大家先容一下到底什么是edge-to-edge全面屏体验。
其实简单来讲,就是让App的界面延伸到手机屏幕的全部空间,这样可以带来更加沉浸式的用户体验。
究竟上,绝大多数的App都没有将界面延伸到手机屏幕的全部空间,因此它们本可以提供更好的用户体验。
这里说的手机屏幕的全部空间详细指的是什么呢?我们看下面这张图就能快速了解了。
https://i-blog.csdnimg.cn/direct/ba6d3a22a5f74aa2a52958bbd457d201.png#pic_center
绝大部分的App其实都只使用了绿色这部分的空间,屏幕上方的状态栏以及屏幕下方的导航栏这两个白色部分的空间都是没有使用起来的,想想你写的App是不是也是这样?
而edge-to-edge全面屏体验就是要将全部的空间都使用起来,如下图所示。
https://i-blog.csdnimg.cn/direct/bee319dbb663418bbc6b6b563a967783.png#pic_center
从上面的两张图对比来看,大概有些朋侪并不会以为edge-to-edge效果带来了多少用户体验的提升。其实这个重要还是得看App的界面计划是什么样的,差别的界面临应出来的edge-to-edge效果也是完全差别的。
这里就让我用一个照片墙App来举行演示吧。照片墙功能其实非常简单,使用RecyclerView就能轻松写出来,这里我就不把照片墙的实现源码帖出来了,因为这部分和我们今天要先容的内容无关,想对源码举行参考的朋侪直接访问下面的GitHub链接即可。
https://github.com/guolindev/Edge2EdgeTest
需要留意的是,一开始我将项目的targetSdkVersion指定的是34,也就是默认不会强制启用edge-to-edge功能。
现在将项目运行到Android 15设备上,效果如下图所示。
https://i-blog.csdnimg.cn/direct/706fc59943f14ba7ba9cca1f03fcdd47.png#pic_center
这个照片墙效果固然不能说是差,只能说中规中矩。毕竟在没有edge-to-edge全面屏体验之前,全部的App都只能做到这个效果。
那么现在有了edge-to-edge功能之后呢?我们来对比看看效果吧。让你的App支持edge-to-edge非常简单,只需要将targetSdkVersion指定成35或更高,就会自动酿成edge-to-edge全面屏效果了,如下图所示。
https://i-blog.csdnimg.cn/direct/77fcb4d9f1ab40d4bef94fe0f3b2b96a.png#pic_center
怎么样,这样一对比,照片墙的沉浸感体验是不是立马就上来了?而且edge-to-edge效果看久了之后,你就再也回不去之前的UI效果了。
另外再说一些关于edge-to-edge全面屏体验的细节。当我们在照片墙上举行滚动时,你会发现屏幕底部导航条的颜色会随着滚动而发生变革。
https://i-blog.csdnimg.cn/direct/f3d55a9a4d4b4e53996a6cefd760b708.gif#pic_center
这个是Android体系自带的功能,为了保证在启用了edge-to-edge全面屏体验之后,底部导航条不会因为因为背景的缘故起因而难以辨认。
发现了这个现象之后,可能细心的朋侪立马就察觉到了,那如果我手机底部的导航栏模式不是这种手势导航栏,而是传统的Back、Home、Task 3按键导航栏,edge-to-edge全面屏体验会酿成什么样呢?
这个结果估计大多数人都猜不到,我们直接来看效果截图吧。
https://i-blog.csdnimg.cn/direct/09047fa9dc824beb9ec0b07f795fa590.png#pic_center
可以看到,导航栏酿成了一种半透明的效果,不透明度默认是80%。
从这个效果上我们也可以看出,3按键导航栏在edge-to-edge全面屏体验方面是完全落后的,这种模式后面就会逐渐被Android体系边沿化了。
同时被边沿化的还有一些与状态栏、导航栏颜色设置相干的API,这些API由于和edge-to-edge全面屏体验是相辩论的,有些是现在就已经不能用了,有些是已经不再保举使用,反正大家看完这篇文章之后只管就别再使用下面这些API了:
Window#setStatusBarColor
Window#setStatusBarContrastEnforced
Window#setNavigationBarColor
Window#setNavigationBarContrastEnforced
文章看到这里,edge-to-edge全面屏体验就已经乐成启用了,但是我们还一行代码都没写呢。
所以,适配edge-to-edge真的一行代码都不用写吗?
固然不是,需不需要对edge-to-edge举行额外的适配工作,重要还是取决于你的界面是什么样的。
像刚才的照片墙界面,由于它非常得当填充满手机屏幕的全部空间,纵然我们不做任何的适配,用户体验仍旧是非常好的。
但是换一个其他的界面就未必云云了。
这里我使用《第一行代码 第3版》第4章的最佳实践项目来作为例子举行演示,看过的读者朋侪们应该都知道这是一个聊天框界面。
同样,由于界面编写不是本篇文章的重点,这里我就不把聊天框的源码实现贴出来了。想对源码举行参考的朋侪可以去查阅《第一行代码 第3版》,或者同样访问上述GitHub链接即可。
我们来看下聊天框界面在edge-to-edge全面屏体验下的效果是什么样的吧,直接上截图。
https://i-blog.csdnimg.cn/direct/4255e25ec8ef4aa589591e9df3de0df3.png#pic_center
可以看到,这次的效果就没有那么理想了。聊天内容进入了状态栏区域,导致部分笔墨内容和状态栏重叠不易阅读,输入框和发送按钮则进入了导航栏区域,导致输入框和按钮操作可能会受到影响。
这些就是最典型的edge-to-edge全面屏体验所带来的问题,而这也正是我们需要去适配的地方。
适配的代码其实还是比较简单的,重要就是借助ViewCompat.setOnApplyWindowInsetsListener()这个函数,来对某些指定的View举行偏移,保证其不会被体系的状态栏或导航栏遮挡住就可以了。
对应到当前的界面,那就是要让顶部的聊天内容不要进入状态栏区域,底部的输入框和发送按钮不要进入导航栏区域,代码如下所示:
class ChatActivity : AppCompatActivity(), View.OnClickListener {

    override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      ...
      ViewCompat.setOnApplyWindowInsetsListener(chatRecyclerView) { v, insets ->
            val stateBars = insets.getInsets(WindowInsetsCompat.Type.statusBars())
            v.setPadding(stateBars.left, stateBars.top, stateBars.right, stateBars.bottom)
            insets
      }
      ViewCompat.setOnApplyWindowInsetsListener(inputTextLayout) { v, insets ->
            val navigationBars = insets.getInsets(WindowInsetsCompat.Type.navigationBars())
            v.setPadding(navigationBars.left, navigationBars.top, navigationBars.right, navigationBars.bottom)
            insets
      }
    }
}
这里给chatRecyclerView和inputTextLayout两个View设置了Insets监听,chatRecyclerView就是聊天内容对应的View,inputTextLayout就是包含输入框和发送按钮的布局。
那么由于我们不盼望聊天内容进入状态栏区域,因此这里调用了WindowInsetsCompat.Type.statusBars()来获取状态栏的Insets,比如说这里获取到状态栏的高度是50,那么我们通过对chatRecyclerView设置一个50的padding就可以保证聊天内容不进入状态栏区域了。
类似地,我们不盼望输入框和发送按钮进入导航栏区域,那么就调用WindowInsetsCompat.Type.navigationBars()来获取导航栏的Insets,之后再用同样的方法来设置padding即可。
加上这一段代码之后,重新运行程序就可以得到比较理想的效果了,如下图所示。
https://i-blog.csdnimg.cn/direct/ffa5fdefa1b84d54b720f724e5e4dde4.png#pic_center
除了WindowInsetsCompat.Type.statusBars()和WindowInsetsCompat.Type.navigationBars()之外,其实我们还有许多其他类型的Insets可供选择。
比如,如果你盼望某个View,既不进入状态栏区域,也不进入导航栏区域,那么可以使用WindowInsetsCompat.Type.systemBars()。
如果你盼望某个View,不会进入到Cutout区域,那么可以使用WindowInsetsCompat.Type.displayCutout()。
Cutout这个概念是Android 9体系时引入的,那个时候手机刚刚鼓起了刘海屏,为了能够适配各式各样可能出现的刘海,Google引入了Cutout API。
不过厥后手机厂商并没有做出各种奇形怪状的刘海,基本都是选择把刘海做到了状态栏里面,所以现在displayCutout()这个API的效果和statusBars()已经没有太大区别了。
想要对刘海屏有更详细的了解,可以参考这篇文章 Android 9新特性,对刘海屏设备举行适配 。
另外从Android 10开始,Google引入了手势导航,这使得手机屏幕的左右两侧可以用于触发Back键操作,手机屏幕的底部可以用于触发Home键操作,触发区域如下图中的黄色部分所示。
https://i-blog.csdnimg.cn/direct/d59fe2bf2ea54a97b260a5dca1a38314.png#pic_center
也就是说,如果我们计划的界面在这个区域有恰好类似的手势操作,那么就会出现手势辩论的情况,导致用户的操作无法正常举行。
这个时候可以使用WindowInsetsCompat.Type.systemGestures()来获得黄色区域的Insets,然后再通过设置padding的方式让有事件辩论的View偏离这个区域就可以了。
基本上关于edge-to-edge全面屏适配要讲的内容也就是这些了,适配的代码还是比较简单的。但是由于它影响到的是全部的项目,而每个项目的UI界面复杂度都各不相同,因此详细会对大家带来多少影响可能还得要大家自己去评估了。
末了,开篇的时候提到过,edge-to-edge全面屏体验其实并不是全新的功能,在Android 15之前也是支持的,Android 15只是将这个功能强制开启了而已。
那么如果我们已经为edge-to-edge全面屏体验做好了适配,就没有任何来由只在Android 15上启用,固然是启用的设备越多越好。
要在Android 15之前的设备上启用edge-to-edge全面屏体验,只需要额外两步就可以完成。
第一步,在项目的build.gradle文件中添加如下库的依靠:
dependencies {
    // For Java
    implementation 'androidx.activity:activity:$activity_version'
    // For Kotlin
    implementation 'androidx.activity:activity-ktx:$activity_version'
}
第二步,在Activity的onCreate函数中添加如下代码:
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
      enableEdgeToEdge()
      super.onCreate(savedInstanceState)
      ...
    }
}
enableEdgeToEdge()是一个Kotlin的扩展函数,用于为旧版Android体系的设备启用edge-to-edge全面屏体验。如果你的项目还在使用Java代码,那么可以使用以下写法替换:
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
      EdgeToEdge.enable(this);
      super.onCreate(savedInstanceState);
      ...
    }
}
完成以上两步之后,edge-to-edge全面屏体验就可以在Android 15之前的设备上启用了,最早可以支持到Android 6.0的设备。
好了,关于edge-to-edge全面屏体验的全部先容就到这里,我们下篇原创再见。

如果想要学习Kotlin和最新的Android知识,可以参考我的新书 《第一行代码 第3版》,点击此处查看详情。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Android 15新特性,强制edge-to-edge全面屏体验