一、前言
Android原生开发到2025年需求已经是寥若星辰,AI的发展也是百花齐放,已经成为Coder的编码得力助手,尽管如此,我还是想把学到的东西消化一番写出来,即便Android开发在这个时代已经没落,想起复旦大学那句民间校训:“自由而无用”。
搁笔三五载,这回有一些时间,业余把公司的项目用Compose写一遍,顺便分享一些开发心得。
二、edge-to-edge
edge-to-edge英译汉就是我们app界面全屏效果的意思,也就是我们常说的沉浸式。在Android15之前,应用默认不是真正的全屏,因为我们APP界面默认不会越界到状态栏和底部栏的区域,而从15开始,则默认强制会延伸到状态栏和底部栏区域,但是兼容与美观程度考虑,我们强制enableEdgeToEdge
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
}
我们应用的界面全屏了,但是可能有些组件,特别是需要用户点击的组件会被覆盖在状态栏或者底部栏,有两种办法解决这个问题,Inset size modifiers和 Padding Modifiers,这里的Inset通常指的就是状态栏、导航栏、软键盘这些系统层面的区域
1.使用占位(Inset size modifiers)
前面说了,edgeToedge之后,我们应用全屏了,我们要避免statusBar和bottomBar覆盖了我们界面的一些按钮之类,我们可以写个占位组件(Spacer就挺好),正好替代这些栏的位置,但是我们不知道要占多少高度,我们需要知道statusBar和bottomBar的信息,而这些信息正是通过WindowInsets
来提供,
状态栏:
WindowInsets.statusBars
底部栏:WindowInsets.navigationBars
如果是想写个占位,比如状态栏我们想单独成白色,那么就可以写一个比如
Box(Modifier.windowInsetsTopHeight(WindowInsets.statusBars).fillMaxWidth().background(Color.White))
通过windowInsetsTopHeight
,把statusBars
传进去,系统就知道我们这里是要占个·statusBars·的高度的位置,还有windowInsetsBottomHeight
,相信你已经知道,就是底部导航栏的高度,把navigateBars传进去,底部占个导航栏位置,实际导航栏我们一般不去设置颜色,直接在根组件设置navigationBarsPadding
也是可以。
2.使用Padding(Padding Modifiers)
可以用Modifier.safeDrawingPadding()
或者safeContentPadding
,这样能够保证我们的应用不被遮挡,这种场景应该是不会常用,我们更多的还是想使用沉浸式标题栏,所以使用方法1可能更有效。在列表,比如LazyColumn
中,我们可能想要列表能穿透systemBar,可以使用contentPadding = WindowInsets.statusBars.asPaddingValues()
之类
以下下这张图就可以很直观地感受到我们上面做的事
三、Inset consumption
到此,我们已经实现了edge-to-edge,还有个概念,Inset consumption
,实际上主要是配合软键盘的弹出与消失,首先还是按照原来的做法,在activity中设置android:windowSoftInputMode="adjustResize"
,接着就是在根组件设置Modifier.imePadding()
,就是弹出键盘时,我们给键盘腾出padding,这样就不会被键盘遮挡住内容.
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun MyScreen() {
Column(
modifier = Modifier.fillMaxSize().systemBarsPadding().imePadding(),
) {
LazyColumn(
modifier = Modifier.weight(1f).imeNestedScroll(),
reverseLayout = true
) {
items(100) { index ->
TextField(
modifier = Modifier.fillMaxWidth(),
value = index.toString(),
onValueChange = { },
)
}
}
}
}
四、小结
这么一小块内容,实际上花费的时间不少,还是没总结到位,但我想基本能满足一些开发需求,有问题我们评论区讨论,过后继续完善。