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

Jetpack Compose实现不同高度卡片的双列同步滚动及下拉刷新

双列高度不一致卡片流的实现方案

方案一:使用官方瀑布流组件(推荐)

Jetpack Compose 已提供LazyVerticalStaggeredGrid组件,专门用于实现不同高度的多列卡片流(瀑布流),完全适配你的需求。双列布局只需指定StaggeredGridCells.Fixed(2),每个卡片可以自由设置不同高度,组件会自动处理错位排列。

示例代码:

LazyVerticalStaggeredGrid(
    columns = StaggeredGridCells.Fixed(2),
    contentPadding = PaddingValues(8.dp),
    horizontalArrangement = Arrangement.spacedBy(8.dp),
    verticalItemSpacing = 8.dp
) {
    items(dataList) { item ->
        // 自定义高度的卡片组件,根据item内容动态设置高度
        Card(
            modifier = Modifier.fillMaxWidth(),
            elevation = 4.dp
        ) {
            Column(modifier = Modifier.padding(16.dp)) {
                Text(item.title, style = MaterialTheme.typography.titleMedium)
                Spacer(modifier = Modifier.height(8.dp))
                Text(item.content, style = MaterialTheme.typography.bodyMedium)
                // 根据内容动态添加高度,比如长文本会自动撑高卡片
            }
        }
    }
    // 分页加载的foot布局
    item {
        if (isLoading) {
            CircularProgressIndicator(modifier = Modifier.fillMaxWidth().padding(16.dp))
        }
    }
}

方案二:自定义双列同步滚动(适用于无法使用StaggeredGrid的场景)

如果因为版本限制无法使用LazyVerticalStaggeredGrid,可以通过外层可滚动容器包裹双列LazyColumn,避免单独滚动的同步偏差问题:

  1. 将数据按奇偶索引拆分左右两个列表
  2. 用带滚动的Column包裹两个LazyColumn,通过外层容器统一控制滚动

示例代码:

val scrollState = rememberScrollState()
val leftList = dataList.filterIndexed { index, _ -> index % 2 == 0 }
val rightList = dataList.filterIndexed { index, _ -> index % 2 != 0 }

Column(modifier = Modifier.verticalScroll(scrollState)) {
    Row(modifier = Modifier.fillMaxWidth()) {
        LazyColumn(
            modifier = Modifier.weight(1f),
            contentPadding = PaddingValues(8.dp),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            items(leftList) { item ->
                CustomCard(item) // 自定义高度卡片
            }
        }
        LazyColumn(
            modifier = Modifier.weight(1f),
            contentPadding = PaddingValues(8.dp),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            items(rightList) { item ->
                CustomCard(item) // 自定义高度卡片
            }
        }
    }
}

这种方式通过外层Column统一滚动,既保留了卡片高度的灵活性,又避免了双列滚动不同步的问题。


SwipeRefresh与Column的结合实现

Compose 官方提供了SwipeRefresh组件,直接包裹带滚动能力的Column即可实现下拉刷新功能,核心是确保Column具备可滚动属性:

示例代码:

val refreshState = rememberSwipeRefreshState(isRefreshing = isRefreshing)
SwipeRefresh(
    state = refreshState,
    onRefresh = {
        // 触发刷新逻辑,比如重新请求第一页数据
        viewModel.refreshData()
    }
) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .verticalScroll(rememberScrollState()),
        verticalArrangement = Arrangement.Top,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        // Column中的内容,比如标题、自定义卡片流等
        Text("页面标题", modifier = Modifier.padding(16.dp))
        // 可嵌入之前实现的双列卡片流
        LazyVerticalStaggeredGrid(...)
    }
}

如果Column内部已经包含LazyColumn、LazyVerticalStaggeredGrid这类自带滚动的组件,也可以直接将SwipeRefresh包裹这些Lazy组件,无需额外给外层Column加滚动属性,避免滚动冲突。

内容的提问来源于stack exchange,提问作者潘星宇

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:01:47