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

Jetpack Compose中如何在内容超最大高度时隐藏元素并显示展开按钮?

实现带自动展开按钮的可折叠卡片组件

你要的需求可以通过onGloballyPositioned修饰符测量内容实际高度,结合Compose的状态驱动重组来实现,完整代码如下:

@Composable
fun CollapsibleCard(
    title: String,
    maxBodyHeight: Dp = 400.dp,
    content: @Composable () -> Unit
) {
    // 控制主体内容的展开/折叠状态
    var isExpanded by remember { mutableStateOf(false) }
    // 记录主体内容的实际渲染高度
    var contentActualHeight by remember { mutableStateOf(0.dp) }
    val density = LocalDensity.current

    Column(
        modifier = Modifier.fillMaxWidth()
            .background(Color.White, RoundedCornerShape(8.dp))
            .padding(16.dp)
    ) {
        // 头部区域
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(text = title, fontSize = 18.sp, fontWeight = FontWeight.Bold)
            
            // 仅当内容高度超过限制且未展开时显示展开按钮
            if (contentActualHeight > maxBodyHeight && !isExpanded) {
                Button(onClick = { isExpanded = true }) {
                    Text("Expand >>")
                }
            }
            
            // 展开状态下显示收起按钮
            if (isExpanded) {
                Button(onClick = { isExpanded = false }) {
                    Text("<< Collapse")
                }
            }
        }

        Spacer(modifier = Modifier.height(8.dp))

        // 主体内容区域
        Box(
            modifier = Modifier
                // 根据展开状态控制高度限制
                .then(if (isExpanded) Modifier else Modifier.heightIn(max = maxBodyHeight))
                // 测量内容实际高度
                .onGloballyPositioned { coordinates ->
                    with(density) {
                        contentActualHeight = coordinates.size.height.toDp()
                    }
                }
        ) {
            content()
        }
    }
}

核心逻辑说明:

  • 状态管理:用remember+mutableStateOf维护两个关键状态,状态变化会自动触发组件重组,更新UI显示。
  • 高度测量:onGloballyPositioned会在组件布局完成后回调,获取内容的实际像素高度并转换为Dp,以此判断是否需要显示展开按钮。
  • 内容控制:未展开时通过heightIn(max = maxBodyHeight)限制主体高度,超出部分自动隐藏;展开后移除高度限制,显示全部内容。
  • 按钮显示逻辑:只有当内容实际高度超过设定的最大限制且处于未展开状态时,才显示展开按钮;展开后切换为收起按钮。

使用示例:

@Composable
fun TestCollapsibleCard() {
    // 模拟超长文本内容
    val hugeContent = buildString {
        repeat(100) {
            append("这是一段用于测试的文本,用来模拟超过最大高度的主体内容。")
        }
    }

    CollapsibleCard(title = "测试卡片") {
        Text(text = hugeContent)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 19:12:57