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

如何将LazyColumn的项置于Card内?遇Composable调用报错

问题解决:Jetpack Compose LazyColumn分组外层加Card的错误处理

你遇到的@Composable invocations can only happen from the context of a @Composable function错误,核心原因是直接在普通的forEach循环里调用Card这个@Composable函数——LazyColumn的content块属于LazyListScope,这里只能使用该作用域提供的扩展方法(比如item、items)来添加Composable内容,普通循环里不能直接调用Composable。

针对你要给整个分组加Card实现整体阴影的需求,正确的做法是把每个分组的标题+整个分组内容都包裹在LazyColumn的item中,让Card在@Composable上下文里被调用,同时用Column承载分组内的所有条目,实现整体包裹效果:

修正后的代码

@Composable
fun ReceiptsListing(navController: NavController, context: Context, locale: Locale) {
    val mappedReceipts = receipts.groupBy { 
        DateUtils.humanizeDatetime(context, locale, it.uploadDate.dateToLocalDateTime()) 
    }
    val listState = rememberLazyListState()
    val coroutineScope = rememberCoroutineScope()

    LazyColumn(
        state = listState,
        modifier = Modifier
            .padding(horizontal = 16.dp)
            .padding(top = 70.dp)
    ) {
        mappedReceipts.forEach { (dateGroup, receiptsInGroup) ->
            // 每个分组对应LazyColumn的一个item
            item {
                // 分组标题
                Text(
                    text = dateGroup,
                    modifier = Modifier
                        .padding(top = 16.dp)
                        .padding(bottom = 8.dp)
                )
                // 包裹整个分组的Card
                Card(elevation = 4.dp) {
                    Column {
                        receiptsInGroup.forEachIndexed { index, receipt ->
                            ReceiptItem(
                                receipt = receipt,
                                cardType = getCardType(index, receiptsInGroup.size),
                            ) {
                                navController.navigate(
                                    ReceiptFragmentDirections.actionReceiptFragment2ToReceiptDetailsFragment2(it)
                                )
                            }
                        }
                    }
                }
            }
        }
    }
}

关键改动说明

  1. 将分组内容放入item块:每个分组的标题和Card都放在LazyColumn的item lambda中,确保所有Composable调用都处于@Composable上下文,解决错误提示问题。
  2. 用Column承载分组内条目:Card内部使用Column遍历分组下的所有ReceiptItem,让整个分组内容都在同一个Card中,实现整体阴影效果,避免单个Card的底部多余线条。
  3. 如果分组条目过多:如果分组内条目数量很大,担心性能问题,可以把Card内部的Column换成嵌套的LazyColumn,并给嵌套的LazyColumn设置合适的高度(比如Modifier.heightIn(max = 400.dp)),避免滚动冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 20:25:16