Search code examples
androidandroid-jetpack-composelazycolumn

LazyColumn inside LazyColumn


I am trying to create and list with sub list using LazyColumn with the code below

DropdownMenu(
    expanded = expandedDomain,
    onDismissRequest = { expandedDomain = false },
) {
    LazyColumn {
        items(1) {
            Checkbox(checked = false /*checkedState.value*/,
                onCheckedChange = {})
            Text(text = "$domainResponse.domains[0].name")
        }
        LazyColumn {
            items(domainResponse.domains[0].pwas) { pwas ->
                Checkbox(checked = false /*checkedState.value*/,
                    onCheckedChange = {})
                Text(text = "$pwas")
            }
        }
    }
}

Error:

@Composable invocations can only happen from the context of a @Composable function

Solution

  • Let me try to explain in parts what you should be changing.

    1. Why did the error occur?

    @Composable invocations can only happen from the context of a @Composable function occurred

    If we peek into LazyColumn code, we can find content: LazyListScope.() -> Unit as the content parameter datatype.

    This shows that the context does not have composable context.

    On contrary, composables like Column/Row would have content: @Composable ColumnScope.() -> Unit/content: @Composable RowScope.() -> Unit respectively.

    The @Composable shows that the content has a Composable context.

    2. How to fix it?

    From what I see in the code, you don't need a LazyColumn inside another LazyColumn. You would need one LazyColumn with multiple items in it from different data sources.

    You can change your code like this,

    LazyColumn {
        item {
            Checkbox(checked = false /*checkedState.value*/,
                onCheckedChange = {})
            Text(text = "$domainResponse.domains[0].name")
        }
        items(domainResponse.domains[0].pwas) { pwas ->
            Checkbox(checked = false /*checkedState.value*/,
                onCheckedChange = {})
            Text(text = "$pwas")
        }
        // You can have multiple lists in a single LazyColumn
        items(list2Items) { item ->
            Text(text = "$item")
        }
    }
    

    3. item vs items

    Use item instead of items(1) if you have a single item as they are equivalent, but this would be more clear.

    P.S:
    LazyColumn uses item or items which have itemContent with composable context. Hence we can add Composables inside them.