在搭载 Android 15 或更高版本的设备上以 SDK 35 或更高版本为目标平台后, 全屏显示。窗口占据整个窗口的宽度和高度 在系统栏后面绘制内容。系统栏包含 标题栏、字幕栏和导航栏。
许多应用都有顶部应用栏。顶部应用栏应拉伸到 屏幕和状态栏后面的显示屏。(可选)顶部应用栏可以 在内容滚动时缩小到状态栏的高度。
许多应用还有一个底部应用栏或底部导航栏。这些条形图应该 也会拉伸到屏幕底部边缘,并显示在导航栏后面 。否则,应用应在导航栏后面显示滚动内容。
<ph type="x-smartling-placeholder">在应用中实现全屏布局时,请在 心态:
- 启用无边框显示屏
- 处理任何视觉重叠。
- 考虑在系统栏后面显示纱罩。
![状态栏后面的图像示例](https://developer.android.google.cn/static/images/guide/navigation/e2e-imagery-behind-status-bar.png?authuser=8&hl=hu)
启用无边框显示屏
如果您的应用以 SDK 35 或更高版本为目标平台,系统会自动为该应用启用无边框 搭载 Android 15 或更高版本的设备。
如需在以前的 Android 版本上启用全屏,请执行以下操作:
向
androidx.activity
库build.gradle
文件:Kotlin
dependencies { val activity_version =
activity_version
// Java language implementation implementation("androidx.activity:activity:$activity_version") // Kotlin implementation("androidx.activity:activity-ktx:$activity_version") }Groovy
dependencies { def activity_version =
activity_version
// Java language implementation implementation 'androidx.activity:activity:$activity_version' // Kotlin implementation 'androidx.activity:activity-ktx:$activity_version' }导入
enableEdgeToEdge
扩展函数:
通过调用 enableEdgeToEdge
手动启用无边框
在Activity
的onCreate
中。应在 setContentView
之前调用它。
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) ... }
Java
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { EdgeToEdge.enable(this); super.onCreate(savedInstanceState); ... }
默认情况下,enableEdgeToEdge()
会让系统栏透明,除了
“三按钮”导航模式,在此模式下,状态栏会有一条半透明的纱罩。通过
根据系统调整系统图标和纱罩的颜色
浅色或深色主题背景。
enableEdgeToEdge()
函数会自动声明应用应
全屏显示并调整系统栏的颜色。
要在您的应用中启用全屏显示,而不使用
enableEdgeToEdge()
函数,请参阅
手动设置无边框显示屏。
使用边衬区处理重叠
应用的某些视图可能会在系统栏后面绘制,如图所示 3.
您可以通过处理边衬区来解决重叠问题,边衬区可指定 屏幕与系统界面(例如导航栏或状态)交叉 。相交可能意味着在内容上方展示 有关系统手势的信息
适用于全屏显示应用的边衬区类型包括:
系统栏边衬区:最适合可点按且不得使用的视图 被系统栏遮挡。
刘海屏边衬区:适用于可能有刘海屏的区域 具体取决于设备的外形
系统手势边衬区:针对系统使用的手势导航区域 优先级高于您的应用的广告
系统栏边衬区
系统栏边衬区是最常用的边衬区类型。它们代表着 应用上方的 Z 轴显示系统界面的区域。它们最棒 用于移动或填充应用中可点按且不得 会被系统栏遮挡。
例如,悬浮操作 图 3 中的按钮 (FAB) 部分功能 以下行为被导航栏遮挡:
![无边框实现的示例,但导航栏覆盖了悬浮操作按钮](https://developer.android.google.cn/static/images/guide/navigation/e2e-after-implementation.png?authuser=8&hl=hu)
为避免在手势模式或按钮模式下出现这种视觉重叠的情况,
可以使用
getInsets(int)
替换为
WindowInsetsCompat.Type.systemBars()
。
以下代码示例展示了如何实现系统栏边衬区:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) // Apply the insets as a margin to the view. This solution sets // only the bottom, left, and right dimensions, but you can apply whichever // insets are appropriate to your layout. You can also update the view padding // if that's more appropriate. v.updateLayoutParams<MarginLayoutParams> { leftMargin = insets.left, bottomMargin = insets.bottom, rightMargin = insets.right, } // Return CONSUMED if you don't want want the window insets to keep passing // down to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); // Apply the insets as a margin to the view. This solution sets only the // bottom, left, and right dimensions, but you can apply whichever insets are // appropriate to your layout. You can also update the view padding if that's // more appropriate. MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams(); mlp.leftMargin = insets.left; mlp.bottomMargin = insets.bottom; mlp.rightMargin = insets.right; v.setLayoutParams(mlp); // Return CONSUMED if you don't want want the window insets to keep passing // down to descendant views. return WindowInsetsCompat.CONSUMED; });
如果将此解决方案应用于图 3 所示的示例,则不会 按钮模式下的视觉重叠,如图 4 所示:
![未覆盖 FAB 的半透明导航栏](https://developer.android.google.cn/static/images/guide/navigation/e2e-system-bars-top.png?authuser=8&hl=hu)
这同样适用于手势导航模式,如图 5 所示:
![通过手势导航实现无边框](https://developer.android.google.cn/static/images/guide/navigation/e2e-system-bars-bottom.png?authuser=8&hl=hu)
刘海屏边衬区
某些设备有刘海屏。通常情况下,刘海屏位于 屏幕,且位于状态栏中。当设备屏幕处于横屏模式时 刘海屏可能位于垂直边缘根据应用的具体内容 您应实现内边距以避免刘海屏,因为 默认情况下,应用会在刘海屏上绘制内容。
例如,许多应用屏幕都会显示项目列表。不要遮盖列表项 刘海屏或系统栏。
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets -> val bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() ) v.updatePadding( left = bars.left, top = bars.top, right = bars.right, bottom = bars.bottom, ) WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> { WindowInsetsCompat bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() ); v.setPadding(bars.left, bars.top, bars.right, bars.bottom); return WindowInsetsCompat.CONSUMED; });
确定 WindowInsetsCompat
的值,只需取以下参数的逻辑“或”
系统栏和刘海屏类型
将 clipToPadding
设置为 RecyclerView
,以便内边距随
。这样一来,当用户将项目移到系统栏后面时,
如下例所示。
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
系统手势边衬区
系统手势边衬区表示窗口区域,您可以在其中进行系统手势 会优先于应用这些区域在图 6 中以橙色显示:
![系统手势边衬区示例](https://developer.android.google.cn/static/images/guide/navigation/e2e-system-gesture-insets.png?authuser=8&hl=hu)
与系统栏边衬区一样,您可以避免与系统手势边衬区重叠
使用
getInsets(int)
替换为
WindowInsetsCompat.Type.systemGestures()
。
使用这些边衬区可将可滑动视图移出边缘或向边缘移动。常见用途
用例包括底部动作条,
使用
ViewPager2
。
在 Android 10 或更高版本中,系统手势边衬区包含 主屏幕手势,以及用于返回手势的左右边衬区:
![系统手势边衬区测量的示例](https://developer.android.google.cn/static/images/guide/navigation/e2e-system-gesture-insets-measurements.png?authuser=8&hl=hu)
以下代码示例展示了如何实现系统手势边衬区:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.updatePadding(insets.left, insets.top, insets.right, insets.bottom) // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()); // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.setPadding(insets.left, insets.top, insets.right, insets.bottom); // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. return WindowInsetsCompat.CONSUMED; });
Material 组件
许多基于 View 的 Android Material 组件
(com.google.android.material){:.external} 会自动处理边衬区,包括
BottomAppBar
,
BottomNavigationView
,
NavigationRailView
和 NavigationView
但是,AppBarLayout
不会自动处理边衬区。将
android:fitsSystemWindows="true"
来处理顶部边衬区或使用 setOnApplyWindowInsetsListener
。
了解如何使用 Compose 中的 Material 组件。
沉浸模式
有些内容在全屏模式下效果最佳,可为用户提供更多
打造沉浸式体验您可以使用以下代码隐藏系统栏以实现沉浸模式
WindowInsetsController
和
WindowInsetsControllerCompat
库:
Kotlin
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) // Hide the system bars. windowInsetsController.hide(Type.systemBars()) // Show the system bars. windowInsetsController.show(Type.systemBars())
Java
Window window = getWindow(); WindowInsetsControllerCompat windowInsetsController = WindowCompat.getInsetsController(window, window.getDecorView()); if (windowInsetsController == null) { return; } // Hide the system bars. windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); // Show the system bars. windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
请参阅隐藏系统栏以实现沉浸模式 。
其他资源
如需详细了解 WindowInsets
手势,请参阅以下参考文档
导航以及边衬区的工作原理: