Compose Multiplatform 中的边缘到边缘布局
Android 要求 SDK 35 及更高版本的应用采用边缘到边缘布局,并且在 SDK 36 中无法选择退出。iOS 应用也预期在状态栏和 Home Indicator 下方绘制内容。从一开始就将每个屏幕构建为边缘到边缘。
规则:背景在系统栏下方绘制;内容和控件通过插边获得内边距。
启用它
Android(在 androidApp 的 MainActivity 中),在 setContent 之前:
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent { App() }
}
在清单中,为 activity 设置 android:windowSoftInputMode="adjustResize",以便 IME 插边能够传递到 Compose。
iOS(ContentView.swift):让 Compose 拥有整个屏幕,否则 SwiftUI 会先应用安全区域,Compose 会看到零插边。
ComposeView().ignoresSafeArea()
Scaffold 完成大部分工作
Scaffold(
topBar = { TopAppBar(title = { Text(title) }) }, // 自身为状态栏留出插边
bottomBar = { NavigationBar { /* ... */ } }, // 自身为导航栏留出插边
) { innerPadding ->
LazyColumn(
contentPadding = innerPadding, // 内容在栏下方滚动
modifier = Modifier.fillMaxSize(),
) { /* items */ }
}
- 始终使用
innerPadding。对于列表,将其作为contentPadding传入,使项目在透明栏后方滚动;对于不可滚动内容,使用Modifier.padding(innerPadding)。 - Material 3 栏会消耗自己的插边。不要在
TopAppBar之上添加statusBarsPadding()。 - 嵌套的 Scaffold 会使插边加倍。为内部 Scaffold 设置
contentWindowInsets = WindowInsets(0),或在外部内容上应用consumeWindowInsets(innerPadding)。
没有 Scaffold 的屏幕
Box(Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)) { // 背景填充屏幕
Column(Modifier.fillMaxSize().windowInsetsPadding(WindowInsets.safeDrawing)) { /* content */ }
}
WindowInsets.safeDrawing 涵盖状态栏、导航栏、屏幕刘海和键盘。当手势重要时使用 safeContent。仅在一次级别上应用插边内边距,即拥有内容的级别,切勿同时应用于父级和子级。
键盘
- 输入屏幕:在滚动容器上使用
Modifier.imePadding(),或使用已经包含 IME 的safeDrawing。 - 必须位于键盘上方的底部按钮:将其放在 scaffold 的
bottomBar中并配合Modifier.imePadding(),或使用WindowInsets.ime.union(WindowInsets.navigationBars)。 - 使内容可滚动,以便获得焦点的字段能够出现在视图中。
全出血内容
图像、地图、视频和相机预览应忽略插边并填充屏幕。在其上方叠加控件,并仅对控件使用 WindowInsets.safeDrawing 添加内边距。
系统栏对比度
系统栏是透明的,因此图标对比度由您负责。在 Android 上,enableEdgeToEdge() 会根据系统主题选择浅色或深色图标;如果应用有自己的主题切换,则在主题更改时使用匹配的 SystemBarStyle 再次调用它。在三按钮导航模式下,Android 会添加一个半透明遮罩;除非底部栏已经提供了实色背景,否则请保留它。
广告横幅
底部横幅应放在 scaffold 的 bottomBar 插槽中,位于导航栏插边之上,并保留其高度,以便内容不会跳动。绝不要将横幅置于手势栏下方或与导航控件重叠;这既是布局错误,也是广告政策问题。
每个屏幕的检查清单
- 背景到达顶部和底部的物理边缘。
- 没有文本或控件位于状态栏、刘海、导航栏或 Home Indicator 下方。
- 最后一个列表项可以在底部栏上方完全滚动。
- 获得焦点的文本字段在键盘打开时保持可见。
- 在横向模式(刘海在侧面)和深色主题下显示正确。
- 插边仅应用一次,没有重复。
如果安装了 Google 的 edge-to-edge 技能,请使用它进行针对 Android 的进一步故障排除。