I have a Composable that shows for each category a line with a dropdown etc and when i try to do a Foreach category do a line in the app so people can click and select a level it shows the Composable error @Composable invocations can only happen from the context of a @Composable function
levels Contains the List Of Categories
LazyColumn(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
levels?.forEach { category ->
CategoryItem(category) //Error happens here
}
}
*emphasized text*
This is what CategoryItem Does:
@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}")
}
)
}
}
}
}
}
With LazyColumn
, you can't use an ordinary loop to emit UI elements. Instead, you need to use the LazyListScope DSL like the item()
and items()
functions. Here's an example:
LazyColumn(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(levels) {
CategoryItem(it)
}
}
Additionally, it's important to use the key parameter within the items()
function, especially when your list items can be reordered.
LazyColumn(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(
items = levels,
key = { it.id }
) { level ->
CategoryItem(level)
}
}