Compose 中的挖孔

显示挖孔是某些设备上延伸到显示屏表面的区域。它允许全屏体验,同时为设备正面重要的传感器提供空间。

Cutout example in portrait mode
图 1. 纵向模式下的挖孔示例
Cutout example in landscape mode
图 2. 横向模式下的挖孔示例

Android 支持在运行 Android 9(API 级别 28)及更高版本的设备上显示挖孔。但是,设备制造商也可以支持在运行 Android 8.1 或更低版本的设备上显示挖孔。

本页面介绍如何在 Compose 中实现对具有挖孔的设备的支持,包括如何使用挖孔区域 - 也就是说,包含挖孔的显示屏表面的全屏矩形。

默认情况

默认情况下,显示挖孔包含在窗口边距信息中。因此,当您遵循有关使您的应用全屏的指南时,您的应用不会在显示挖孔区域中绘制。

例如,当您使用 Modifier.windowInsetsPadding(WindowInsets.safeContent)Modifier.windowInsetsPadding(WindowInsets.safeDrawing) 时,您的应用会自动不在放置挖孔的区域中绘制。 WindowInsets.safeContentWindowInsets.safeDrawing 都包含显示挖孔信息,并且不会在设备挖孔所在的位置绘制。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    WindowCompat.setDecorFitsSystemWindows(window, false)

    setContent {
        Box(Modifier.windowInsetsPadding(WindowInsets.safeContent)) {
            // Any composable inside here will avoid drawing behind cutouts
        }
    }
}

要进一步自定义此行为,您需要自己处理挖孔信息。

手动处理挖孔信息

您可以通过以下任一方式处理挖孔

对于 Compose,建议在整体主题中将 windowLayoutInDisplayCutoutMode 设置为 default,然后利用 WindowInsets.displayCutout 在您的可组合项中处理边距

Canvas(modifier = Modifier.fillMaxSize().windowInsetsPadding(WindowInsets.displayCutout)) {
    drawRect(Color.Red, style = Stroke(2.dp.toPx()))
}

这种方法允许您在需要时尊重 displayCutout 填充,或者在不需要时忽略它。

或者,您可以通过将活动主题 android:windowLayoutInDisplayCutoutMode 设置为另一个选项,或使用 window.attributes.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT 设置窗口属性,来应用与视图挖孔文档中描述的相同设置。但是,挖孔模式然后将应用于整个活动,并且无法按单个可组合项进行控制。

要在某些可组合项中尊重显示挖孔,而在其他可组合项中不尊重,请使用 WindowInset.displayCutout。此 API 允许您在需要时访问挖孔信息。

最佳实践

在处理显示挖孔时,请考虑以下事项

  • 注意 UI 中关键元素的放置位置。不要让挖孔区域遮挡任何重要的文本、控件或其他信息。
  • 不要将需要精细触控识别的任何交互式元素放置或扩展到挖孔区域。挖孔区域的触控灵敏度可能较低。
  • 遵循全屏指南时,挖孔信息包含在 safeDrawing / safeContent 边距中。
  • 尽可能使用 Modifier.windowInsetsPadding(WindowInsets.safeDrawing) 来确定应用于您的内容的适当填充。避免硬编码状态栏高度,因为这会导致内容重叠或被切断。

测试您的内容在挖孔中是如何渲染的

务必测试您的应用的所有屏幕和体验。如果可能,在具有不同类型挖孔的设备上进行测试。如果您没有带挖孔的设备,则可以通过以下操作,在运行 Android 9 或更高版本的任何设备或模拟器上模拟常见的挖孔配置

  1. 启用 开发者选项.
  2. 开发者选项屏幕中,向下滚动到绘制部分,然后选择模拟具有挖孔的显示屏
  3. 选择挖孔类型。
    simulating a display cutout in the emulator
    图 3. 使用开发者选项测试您的内容是如何渲染的。