I have found that
val list: List<@Composable ()-> Unit> = listOf({Text("Cat")}, {Text("Dog")})
works, but
val list: List<@Composable ()-> Unit> = listOf({Text("Cat")}) + listOf({Text("Dog")})
produces the error "@Composable
invocations can only happen from the context of a @Composable
function" on the first Text()
.
Why is it that adding lists works fine with things like
val list: List<String> = listOf("Cat") + listOf("Dog")
but doesn't seem to work with Composables? Is there a way how I can add lists of Composables to each other?
The difference in behavior between the two scenarios is related to how Jetpack Compose handles the @Composable
functions and the context in which they are invoked.
In the first scenario:
val list: List<@Composable ()-> Unit> = listOf({Text("Cat")}, {Text("Dog")})
Both Text("Cat") and Text("Dog")
are wrapped in @Composable lambda expressions within the list. When you use the list directly, the lambda expressions are invoked within the context of a @Composable function.
In the second scenario:
val list: List<@Composable ()-> Unit> = listOf({Text("Cat")}) + listOf({Text("Dog")})
Here, you are using the +
operator to concatenate two lists. The resulting list contains two @Composable
lambda expressions, but they are not automatically invoked within a @Composable
context.
To Better understand, try with this example
@Composable
fun MainView() {
val list: List<@Composable () -> Unit> = combineComposableLists()
// Important: Render each composable in the combined list
list.forEach { composable -> composable() }
}
@Composable
fun combineComposableLists(): List<@Composable () -> Unit> {
val list1: List<@Composable () -> Unit> = getList1()
val list2: List<@Composable () -> Unit> = getList2()
return list1 + list2
}
@Composable
fun getList1(): List<@Composable () -> Unit> {
return listOf(
{ Text("Cat") },
{ Text("Dog") }
)
}
@Composable
fun getList2(): List<@Composable () -> Unit> {
return listOf(
{ Text("Fish") },
{ Text("Bird") }
)
}