关于系统栏保护

一旦您的应用目标 SDK 达到 35 或更高版本,边缘到边缘就会强制执行。系统状态栏和手势导航栏是透明的,但三按钮导航栏是半透明的。调用 enableEdgeToEdge 可以使其向后兼容。

然而,系统默认值可能不适用于所有用例。请查阅Android 系统栏设计指南边缘到边缘设计指南,了解何时考虑使用透明或半透明系统栏的概览。

创建透明系统栏

通过以 Android 15 或更高版本为目标,或者为更早版本调用带有默认参数的 enableEdgeToEdge() 来创建透明手势导航栏。对于三按钮导航栏,将 Window.setNavigationBarContrastEnforced 设置为 false,否则将应用半透明遮罩。

创建半透明系统栏

要创建半透明状态栏,请创建一个自定义可组合项,该可组合项与主内容重叠并在内边距覆盖的区域绘制渐变。

class SystemBarProtectionSnippets : ComponentActivity() {

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

        // enableEdgeToEdge sets window.isNavigationBarContrastEnforced = true
        // which is used to add a translucent scrim to three-button navigation
        enableEdgeToEdge()

        setContent {
            MyTheme {
                // Main content
                MyContent()

                // After drawing main content, draw status bar protection
                StatusBarProtection()
            }
        }
    }
}

@Composable
private fun StatusBarProtection(
    color: Color = MaterialTheme.colorScheme.surfaceContainer,
    heightProvider: () -> Float = calculateGradientHeight(),
) {

    Canvas(Modifier.fillMaxSize()) {
        val calculatedHeight = heightProvider()
        val gradient = Brush.verticalGradient(
            colors = listOf(
                color.copy(alpha = 1f),
                color.copy(alpha = .8f),
                Color.Transparent
            ),
            startY = 0f,
            endY = calculatedHeight
        )
        drawRect(
            brush = gradient,
            size = Size(size.width, calculatedHeight),
        )
    }
}

@Composable
fun calculateGradientHeight(): () -> Float {
    val statusBars = WindowInsets.statusBars
    val density = LocalDensity.current
    return { statusBars.getTop(density).times(1.2f) }
}

图 1. 半透明状态栏。

对于自适应应用,请插入一个与每个窗格颜色匹配的自定义可组合项,如边缘到边缘设计中所示。要创建半透明导航栏,请将 Window.setNavigationBarContrastEnforced 设置为 true。