You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Material3 NavigationBar如何同步设置系统导航栏colorElevation为1.dp?

解决方案

要同步Compose NavigationBar与Android系统导航栏的elevation,需要分别处理Compose组件层面和系统Window层面的设置,同时兼顾页面复用后的状态恢复。以下是最优实现方案:

核心思路

NavigationBar的tonalElevation是Compose组件自身的阴影效果,而系统导航栏的elevation是Android Window层面的属性,两者独立。需要通过DisposableEffect绑定当前页面的生命周期,设置系统导航栏的elevation并在页面销毁时恢复原有状态,避免影响其他页面。

完整代码实现

@Composable
fun MainScreen(navigationTabs: List<NavigationTab>) {
    val view = LocalView.current
    val window = remember { (view.context as Activity).window }
    val targetElevation = 1.dp // 与NavigationBar的tonalElevation保持一致

    // 绑定生命周期:设置系统导航栏elevation,页面销毁时恢复原有状态
    DisposableEffect(targetElevation) {
        val originalElevation = window.navigationBarElevation
        val originalColor = window.navigationBarColor
        var originalAppearance = 0

        // 应用新的系统导航栏设置
        window.navigationBarElevation = targetElevation.toPx()
        window.navigationBarColor = Color.Transparent.toArgb() // 适配透明导航栏

        // 兼容Android 11(API 30)及以上版本的阴影控制
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            val insetsController = window.insetsController
            originalAppearance = insetsController?.systemBarsAppearance ?: 0
            // 确保显示系统导航栏阴影
            insetsController?.setSystemBarsAppearance(
                originalAppearance or WindowInsetsController.APPEARANCE_SHOW_NAVIGATION_BAR_SHADOW,
                WindowInsetsController.APPEARANCE_SHOW_NAVIGATION_BAR_SHADOW
            )
        } else {
            // 低版本开启系统栏背景绘制权限,确保阴影显示
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
        }

        // 页面销毁时恢复系统导航栏原有配置
        onDispose {
            window.navigationBarElevation = originalElevation
            window.navigationBarColor = originalColor
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                window.insetsController?.setSystemBarsAppearance(
                    originalAppearance,
                    WindowInsetsController.APPEARANCE_SHOW_NAVIGATION_BAR_SHADOW
                )
            }
        }
    }

    Scaffold(
        content = { padding ->
            Box(modifier = Modifier.padding(bottom = padding.calculateBottomPadding())) {
                CurrentTab()
            }
        },
        bottomBar = {
            NavigationBar(
                containerColor = MaterialTheme.colorScheme.surface,
                contentColor = MaterialTheme.colorScheme.secondaryContainer,
                tonalElevation = targetElevation,
            ) {
                navigationTabs.forEach {
                    TabNavigationItem(it)
                }
            }
        },
    )
}

关键细节说明

  1. 生命周期绑定:使用DisposableEffect确保只有当前页面显示时才修改系统导航栏配置,页面销毁后自动恢复,不会影响其他复用该系统导航栏的页面。
  2. elevation同步:将系统导航栏的navigationBarElevation设置为与NavigationBar的tonalElevation相同的像素值(通过dp.toPx()转换)。
  3. 透明导航栏适配:设置window.navigationBarColor = Color.Transparent.toArgb()确保系统导航栏保持透明,同时开启阴影显示权限。
  4. 版本兼容:针对Android 11及以上版本使用WindowInsetsController控制阴影,低版本通过Window flags开启背景绘制权限。

内容的提问来源于stack exchange,提问作者mitua1221

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 06:55:22