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

SDK35迁移后Compose Dialog Bottom Sheet导航栏内边距为0问题

Android SDK35下Compose Dialog自定义Bottom Sheet导航栏Insets获取失效解决办法

解决方案

直接从宿主Activity的WindowInsets中获取导航栏高度,手动为Bottom Sheet设置底部内边距,替代Compose内置的Insets修饰符。

完整代码示例

import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Dialog
import androidx.compose.material3.DialogProperties
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowInsetsCompat
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper

@Composable
fun ActionSheetDialog(
    actionSheet: StateFlow<ActionSheetViewModel?>,
    displayDelay: Duration = 100.milliseconds
) {
    val activity = LocalContext.current.findActivity()
    val navigationBarHeight by remember {
        derivedStateOf {
            val windowInsets = WindowInsetsCompat.toWindowInsetsCompat(activity.window.decorView.rootWindowInsets)
            val insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars())
            insets.bottom.toDp()
        }
    }

    Dialog(
        onDismissRequest = { /* 处理关闭逻辑 */ },
        properties = DialogProperties(
            usePlatformDefaultWidth = false,
            decorFitsSystemWindows = false
        )
    ) {
        Box(
            Modifier
                .fillMaxSize()
                .clickable(
                    indication = null,
                    interactionSource = remember { MutableInteractionSource() }
                ) { /* 点击空白处关闭 */ }
        ) {
            Column(
                Modifier
                    .align(Alignment.BottomCenter)
                    .padding(bottom = navigationBarHeight)
                    .imePadding()
                    .fillMaxWidth()
                    .padding(horizontal = 8.dp)
                    .clickable(enabled = false) {}
            ) {
                // Bottom Sheet内容区域
            }
        }
    }
}

// 扩展函数:从Context向上查找关联的Activity
fun Context.findActivity(): Activity {
    var context = this
    while (context is ContextWrapper) {
        if (context is Activity) return context
        context = context.baseContext
    }
    throw IllegalStateException("当前Context未关联任何Activity")
}

原因分析

  1. Dialog与Activity的Window隔离:SDK35中,Compose Dialog的Window独立于宿主Activity,默认不会同步Activity的WindowInsets数据,导致navigationBarsPadding()等内置修饰符无法获取真实导航栏高度,返回值为0。
  2. decorFitsSystemWindows设置:必须将DialogProperties中的decorFitsSystemWindows设为false,否则Dialog会自动调整布局填充系统栏区域,手动设置的内边距会被覆盖或失效。

注意事项

  • 横竖屏切换时,derivedStateOf会自动重新计算导航栏高度,无需额外适配逻辑。
  • 兼容三键导航、手势导航模式及不同屏幕尺寸设备。
  • 确保项目依赖androidx.core:core-ktx(版本建议与Compose版本匹配),以支持WindowInsetsCompat相关API。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 06:43:11