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

Jetpack Compose中不同行Card组件阴影不一致问题排查

Jetpack Compose数字键盘Card阴影差异问题解决

问题现象

数字键盘组件中,第一行Card的阴影清晰可见,最后一行的Card阴影却几乎消失,视觉效果差异明显。

问题原因

  1. 布局空间不足导致阴影裁剪:Card的阴影绘制在自身边界之外,如果父布局(Column或Row)未预留足够空间,阴影会被容器边缘裁剪。最后一行Row仅包含单个Card且未设置填充宽度,导致Card靠近Column底部边缘,阴影被裁剪。
  2. Row布局不一致:前3行Row用Arrangement.spacedBy排列三个Card,最后一行Row仅居中放置一个Card,布局宽度的差异可能影响Compose的阴影渲染逻辑。

解决方案

通过调整布局预留阴影绘制空间、统一Row布局方式解决:

修改后的代码

@Composable
@Preview
fun DigitalKeyboardCompose(
    gap: Dp = 16.dp,
    sizeInDP: Dp = 64.dp,
    isEnabled: Boolean = true,
    disableColor: Int = android.graphics.Color.GRAY,
    onClick: ((Int) -> Unit)? = null
) {
    Column(
        Modifier
            .fillMaxWidth()
            .padding(vertical = gap), // 给Column加垂直内边距,避免上下边缘裁剪阴影
        Arrangement.spacedBy(gap, Alignment.CenterVertically),
        Alignment.CenterHorizontally
    ) {
        repeat(3) { i ->
            Row(
                modifier = Modifier.fillMaxWidth(), // 统一所有Row宽度为填充父布局
                horizontalArrangement = Arrangement.SpaceEvenly // 用均匀分布替代固定间距,保证布局一致性
            ) {
                repeat(3) { j ->
                    DigitalKeyboardKey(sizeInDP, i * 3 + j + 1, isEnabled, disableColor, onClick)
                }
            }
        }
        Row(
            modifier = Modifier.fillMaxWidth(), // 最后一行Row同样设置填充宽度
            horizontalArrangement = Arrangement.Center
        ) {
            DigitalKeyboardKey(sizeInDP, 0, isEnabled, disableColor, onClick)
        }
    }
}

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun DigitalKeyboardKey(size: Dp, key: Int, isEnabled: Boolean, disableColor: Int, onClick: ((Int) -> Unit)?) {
    Card(
        elevation = 4.dp,
        modifier = Modifier
            .width(size)
            .height(size)
            .padding(4.dp), // 给Card加内边距,确保阴影有足够绘制空间
        border = BorderStroke(1.dp, if (isEnabled) MaterialTheme.colors.primary else Color(disableColor)),
        shape = RoundedCornerShape(8.dp),
        enabled = isEnabled,
        onClick = { if (isEnabled) onClick?.invoke(key) }
    ) {
        Box(contentAlignment = Alignment.Center) {
            Text(
                key.toString(),
                color = if (isEnabled) MaterialTheme.colors.primary else Color(disableColor),
                fontFamily = FontFamily.SansSerif,
                fontWeight = FontWeight(500),
                fontSize = 28.sp
            )
        }
    }
}

关键修改点

  • 外层Column添加padding(vertical = gap):为上下边缘的Card预留阴影绘制空间,避免阴影被容器裁剪。
  • 所有Row设置Modifier.fillMaxWidth():统一Row布局宽度,消除因Row宽度不同导致的阴影渲染差异。
  • Card添加padding(4.dp):确保Card自身的阴影不会被父Row的边界裁剪。
  • 简化Text字体大小写法:用28.sp替代TextUnit(28f, TextUnitType.Sp),符合Compose最佳实践。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:25:30