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

LazyColumn调用@Composable函数报错:仅可在@Composable上下文执行

解决Jetpack Compose中LazyColumn遍历调用Composable的错误

问题描述

实现了@Composable组件CategoryItem用于展示带下拉菜单的类别行,但在LazyColumn中遍历列表levels生成组件时,出现错误:@Composable invocations can only happen from the context of a @Composable function。

错误代码

LazyColumn(
             modifier = Modifier.fillMaxWidth(),
             verticalArrangement = Arrangement.spacedBy(8.dp)
          ) {
             levels?.forEach { category ->
                 CategoryItem(category) // 报错位置
            }
        }

CategoryItem实现

@Composable
fun CategoryItem(category: Category) {
    var expanded by remember { mutableStateOf(false) }

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp)
    ) {
        ClickableSquare(
            onClick = { expanded =!expanded },
            text = category.name
        )

        if (expanded) {
            DropdownMenu(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(horizontal = 16.dp),
                expanded = expanded,
                onDismissRequest = { expanded = false }
            ) {
                category.levels.forEach { level ->
                    DropdownMenuItem(
                        text = { Text(text = level.name) },
                        onClick = {
                            // Navigate to GameScreen with level data
                            navController.navigate(route = AppScreens.GameScreen.route + "/${level.code}")
                        }
                    )
                }
            }
        }
    }
}

错误原因

LazyColumn的代码块属于LazyListScope作用域,并非标准的@Composable上下文。直接使用普通forEach遍历并调用@Composable函数,会脱离Composable上下文约束,触发报错。

解决方案

使用LazyColumn提供的items或itemsIndexed方法遍历列表,这些方法内部维护了Composable上下文,可安全调用@Composable组件。

修改后的代码

LazyColumn(
    modifier = Modifier.fillMaxWidth(),
    verticalArrangement = Arrangement.spacedBy(8.dp)
) {
    levels?.let { categories ->
        items(categories) { category ->
            CategoryItem(category)
        }
    }
}

若需要使用列表索引,可改用itemsIndexed:

LazyColumn(
    modifier = Modifier.fillMaxWidth(),
    verticalArrangement = Arrangement.spacedBy(8.dp)
) {
    levels?.let { categories ->
        itemsIndexed(categories) { index, category ->
            CategoryItem(category)
        }
    }
}

内容的提问来源于stack exchange,提问作者Ángel David Gutierrez Orellana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:27:17