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

Jetpack Compose 展开内容时涟漪效果适配异常问题

解决Jetpack Compose中展开Surface的涟漪适配问题

你遇到的问题确实是因为涟漪效果触发时就绑定了当时的Surface尺寸,后续组件展开时涟漪不会动态更新,导致出现过小或中断的情况。下面提供三种可行的解决思路:

方法一:自定义涟漪追踪最终尺寸

通过MutableInteractionSource和自定义indication,让涟漪基于组件的最终尺寸生成,即使展开动画还在进行中:

var expanded by remember { mutableStateOf(false) }
val interactionSource = remember { MutableInteractionSource() }
// 计算组件最终高度:收起时50dp,展开时250dp
val finalHeight = if (expanded) 250.dp else 50.dp

Column(modifier = Modifier.fillMaxSize()) {
    Surface(
        color = Color.Gray,
        interactionSource = interactionSource,
        indication = rememberRipple(
            bounded = true,
            radius = finalHeight / 2
        ),
        onClick = { expanded = !expanded }
    ) {
        Column {
            Box(Modifier.fillMaxWidth().height(50.dp))
            AnimatedVisibility(visible = expanded) {
                Box(Modifier.fillMaxWidth().height(200.dp))
            }
        }
    }
}

方法二:分离点击区域与内容层

用一个固定最终尺寸的透明点击层覆盖在内容上方,让涟漪一开始就基于完整容器尺寸生成,内容的展开动画在下方正常执行:

var expanded by remember { mutableStateOf(false) }
// 组件展开后的总高度
val totalHeight = 250.dp

Column(modifier = Modifier.fillMaxSize()) {
    Box(modifier = Modifier.width(IntrinsicSize.Max)) {
        // 内容层:随状态展开/收起
        Column {
            Surface(color = Color.Gray) {
                Box(Modifier.fillMaxWidth().height(50.dp))
            }
            AnimatedVisibility(visible = expanded) {
                Surface(color = Color.Gray) {
                    Box(Modifier.fillMaxWidth().height(200.dp))
                }
            }
        }
        // 透明点击层:始终占满最终尺寸,负责触发涟漪
        Surface(
            color = Color.Transparent,
            modifier = Modifier.matchParentSize(),
            onClick = { expanded = !expanded }
        ) {}
    }
}

方法三:用AnimatedContent同步尺寸与涟漪

通过AnimatedContent让Surface的尺寸动画和涟漪效果同步,确保涟漪能跟随组件尺寸动态更新:

var expanded by remember { mutableStateOf(false) }

Column(modifier = Modifier.fillMaxSize()) {
    AnimatedContent(targetState = expanded, label = "expand_content") { isExpanded ->
        Surface(
            color = Color.Gray,
            onClick = { expanded = !expanded }
        ) {
            Column {
                Box(Modifier.fillMaxWidth().height(50.dp))
                if (isExpanded) {
                    Box(Modifier.fillMaxWidth().height(200.dp))
                }
            }
        }
    }
}

其中方法二更贴合Material 3搜索栏的实现逻辑——点击区域始终覆盖完整容器范围,涟漪自然能延伸到展开后的整个区域。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:33:28