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 设置窗口属性来应用 Views 挖孔文档 中描述的相同设置。但是,挖孔模式随后会应用于整个活动,并且无法按单个可组合项进行控制。

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

最佳实践

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

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

测试内容在挖孔中的渲染方式

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

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