随着Android 15(API 35)的发布,Google继续推动沉浸式全面屏UI设计。虽然这种设计提升了现代应用的视觉体验,但也引入了一些细微变化,可能会破坏现有布局——特别是如果你的应用依赖精确处理系统栏的话。本文将探讨如何为API 35迁移你的Jetpack Compose应用,并讨论管理全面屏UI过渡的最佳实践。
起点:当前设置
让我们看一个基本的Compose设置,包含白色工具栏和底部导航栏:
@Composable
fun MainScreen() {
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = "全面屏示例") },
actions = {
IconButton(onClick = { /* 处理设置 */ }) {
Icon(Icons.Default.Settings, contentDescription = "设置")
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = Color.White,
titleContentColor = Color.Black
)
)
},
bottomBar = {
BottomAppBar(
containerColor = Color.White,
contentColor = Color.Black
) {
IconButton(onClick = { /* 处理主页操作 */ }) {
Icon(Icons.Default.Home, contentDescription = "主页")
}
Spacer(modifier = Modifier.weight(1f))
IconButton(onClick = { /* 处理搜索操作 */ }) {
Icon(Icons.Default.Search, contentDescription = "搜索")
}
Spacer(modifier = Modifier.weight(1f))
IconButton(onClick = { /* 处理个人资料操作 */ }) {
Icon(Icons.Default.Person, contentDescription = "个人资料")
}
}
},
content = { innerPadding ->
Box(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
.background(Color.Gray),
contentAlignment = Alignment.Center
) {
Text(
text = "Content goes here on API ${Build.VERSION.SDK_INT}上",
fontSize = 22.sp
)
}
}
)
}
对应的运行效果如下。
可以看到,由于全面屏的变化,这个设置在API 34和API 35上的表现不同:
状态栏:
-
API 34:由于透明性,反映了灰色内容背景
-
API 35:默认为白色以保持一致性,但如果未配置则缺少可见图标
导航栏:
-
API 34:默认为黑色,因为没有显式配置
-
API 35:继承应用的白色BottomAppBar颜色以实现无缝外观
虽然这些变化符合现代设计标准,但它们需要调整以实现向后兼容性和视觉一致性。
解决方案:启用全面屏
要有效实现全面屏功能,你可以使用WindowCompat和WindowInsetsControllerCompat进行配置,示例代码如下。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 启用全面屏模式
// 这会禁用默认系统行为,即窗口内容调整为适合系统栏(状态栏和导航栏)内部
// 通过将此设置为false,允许应用内容绘制在系统栏下方,创建沉浸式全面屏体验
// 然后你可以使用insets和修饰符管理内容如何与这些栏交互
WindowCompat.setDecorFitsSystemWindows(window, false)
// 调整状态栏和导航栏外观
val insetsController = WindowInsetsControllerCompat(window, window.decorView)
insetsController.isAppearanceLightStatusBars = true
insetsController.isAppearanceLightNavigationBars = true
// 可选:为状态栏和导航栏设置特定颜色
window.statusBarColor = android.graphics.Color.TRANSPARENT
window.navigationBarColor = android.graphics.Color.TRANSPARENT
setContent {
MainScreen()
}
}
}
再次运行项目,即可看到系统栏图标保持可见并与应用主题对齐。
高级配置:窗口Insets
为了在Jetpack Compose中精确控制insets,你可以使用内置修饰符如Modifier.windowInsetsPadding或Scaffold中的contentWindowInsets参数。这些工具允许你动态调整应用布局以适应系统栏区域,确保完美的全面屏体验。
Modifier.windowInsetsPadding
这个修饰符根据特定的系统insets(如状态栏、导航栏或系统手势)为你的可组合项添加填充。
Box(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.systemBars)
) {
Text("内容系统栏")
}
WindowInsets.systemBars的值会动态调整状态栏和导航栏的填充。
Scaffold中的contentWindowInsets
contentWindowInsets参数确保脚手架内容动态考虑系统insets以进行适当的布局调整。
Scaffold(
contentWindowInsets = WindowInsets.systemBars,
content = { innerPadding ->
Box(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),
contentAlignment = Alignment.Center
) {
Text("系统栏填充的内容")
}
}
)
组合使用
对于复杂布局,可以将Modifier.windowInsetsPadding与其他布局修饰符结合使用来微调应用的UI。
Column(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.systemBars)
) {
Text("顶部内容")
Spacer(modifier = Modifier.weight(1f))
Text("底部内容")
}
通过利用上面的这些方式,可以创建一个响应式和沉浸式的UI,遵循全面屏原则而不影响可用性。