在应用中全屏显示内容

试用 Compose 方式
Jetpack Compose 是推荐在 Android 设备上使用的界面工具包。了解如何在 Compose 中使用无边框功能。

在搭载 Android 15 或更高版本的设备上以 SDK 35 或更高版本为目标平台后, 全屏显示。窗口占据整个窗口的宽度和高度 在系统栏后面绘制内容。系统栏包含 标题栏、字幕栏和导航栏。

许多应用都有顶部应用栏。顶部应用栏应拉伸到 屏幕和状态栏后面的显示屏。(可选)顶部应用栏可以 在内容滚动时缩小到状态栏的高度。

许多应用还有一个底部应用栏或底部导航栏。这些条形应该 也会拉伸到屏幕底部边缘,并显示在导航栏后面 。否则,应用应在导航栏后面显示滚动内容。

<ph type="x-smartling-placeholder">
图 1.无边框布局中的系统栏。

在应用中实现全屏布局时,请在 心态:

  1. 启用无边框显示屏
  2. 处理任何视觉重叠。
  3. 考虑在系统栏后面显示纱罩。
。 <ph type="x-smartling-placeholder">
</ph> 状态栏后面的图像示例
图 2.背后图像示例 。

启用无边框显示

如果您的应用以 SDK 35 或更高版本为目标平台,系统会自动为该应用启用无边框 搭载 Android 15 或更高版本的设备。

如需在以前的 Android 版本上启用全屏,请执行以下操作:

  1. androidx.activitybuild.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'
    }
  2. 导入 enableEdgeToEdge 扩展函数:

通过调用 enableEdgeToEdge 手动启用无边框 在ActivityonCreate中。应在 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) 部分功能 以下行为被导航栏遮挡:

无边框实现的示例,但导航栏覆盖了悬浮操作按钮
图 3. 导航栏与 FAB 中的 FAB 重叠 无边框布局。

为避免在手势模式或按钮模式下出现这种视觉重叠的情况, 可以使用 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 的半透明导航栏
图 4. 解决按钮中的视觉重叠问题 模式。

这同样适用于手势导航模式,如图 5 所示:

通过手势导航实现无边框
图 5. 解决手势中的视觉重叠问题 导航模式。

刘海屏边衬区

某些设备有刘海屏。通常情况下,刘海屏位于 屏幕,且位于状态栏中。当设备屏幕处于横屏模式时 刘海屏可能位于垂直边缘根据应用的具体内容 您应实现内边距以避免刘海屏,因为 默认情况下,应用会在刘海屏上绘制内容。

例如,许多应用屏幕都会显示项目列表。不要遮盖列表项 刘海屏或系统栏。

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) -> {
  Insets 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 中以橙色显示:

系统手势边衬区示例
图 6. 系统手势边衬区。

与系统栏边衬区一样,您可以避免与系统手势边衬区重叠 使用 getInsets(int) 替换为 WindowInsetsCompat.Type.systemGestures()

使用这些边衬区可将可滑动视图移出边缘或向边缘移动。常见用途 用例包括底部动作条, 使用 ViewPager2

在 Android 10 或更高版本中,系统手势边衬区包含 主屏幕手势,以及用于返回手势的左右边衬区:

系统手势边衬区测量的示例
图 7. 系统手势边衬区测量结果。

以下代码示例展示了如何实现系统手势边衬区:

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, NavigationRailViewNavigationView

但是,AppBarLayout 不会自动处理边衬区。将 android:fitsSystemWindows="true" 来处理顶部边衬区或使用 setOnApplyWindowInsetsListener

了解如何使用 Compose 中的 Material 组件

沉浸模式

有些内容在全屏模式下效果最佳,可为用户提供更多 打造沉浸式体验您可以使用以下代码隐藏系统栏以实现沉浸模式 WindowInsetsControllerWindowInsetsControllerCompat 库:

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 手势,请参阅以下参考文档 导航以及边衬区的工作原理: