Home > Mobile >  How to add a list of composables as parameter
How to add a list of composables as parameter

Time:07-07

Im trying to pass a list of Composables, in this case Columns, as a parameter to later populate a view, for that I'm adding the parameter List<@Composable (ColumnScope.() -> Unit)> on a composable function and populating a List with simple Columns.

The problem I'm having is that the Columns generate a Type mismatch

Required:
List<ColumnScope.() → Unit>
Found:
List<Unit>

Is there a way to achieve this? Here I'll provide my code.

@Composable
fun LotsOfColumns() {
    ColumnListSample(
        myColumns = listOf(
            Column {}, 
            Column {}
        )
    )
}

@Composable
fun ColumnListSample(
    myColumns: List<@Composable (ColumnScope.() -> Unit)>,
    modifier: Modifier = Modifier
) {}

CodePudding user response:

@Composable fun LotsOfColumns() {
    ColumnListSample(
        myColumns = listOf(
            { Column {} },
            { Column {} }
        )
    )
}

CodePudding user response:

I do this by wrapping @Composable functions inside a data class or a class then pass that class with a List

data class TutorialSectionModel(
    val title: String,
    val action: @Composable (() -> Unit)? = null,
    val description: String,
    val tags: List<String> = listOf(),
    val tagColor: Color = DefaultListColor,
    var expanded: Boolean = false
)

And create a list of that class that contains that Composables and i pass them to my LazyColumn.

val tutorialList = mutableListOf<List<TutorialSectionModel>>()

Use it with LazyColumn

        LazyColumn(

            content = {

                items(
                    items = tutorialList,
                    key = {
                        it.title
                    }
                ) { item: TutorialSectionModel ->

                    var isExpanded by remember(key1 = item.title) { mutableStateOf(item.expanded) }

                    TutorialSectionCard(
                        model = item,
                        onClick = {
                            navigateToTutorial(item.title)
                        },
                        onExpandClicked = {
                            item.expanded = !item.expanded
                            isExpanded = item.expanded
                        },
                        expanded = isExpanded
                    )
                }
            }

You can pass your @Composable (ColumnScope.() -> Unit to a class you created same way.

Maybe not in your question scope, the way wrapping inside a class helps passing this list to a ViewModel and i use this action or Composables as navigation target too instead of writing tens of composable navigation routes.

    // Set navigation route as title of tutorial card
    // and invoke @Composable inside lambda of this card.
    mainViewModel.tutorialList.forEach { list ->
        list.forEach { model ->
            composable(route = model.title) { navBackEntryStack ->
                // This column is used for setting navigation padding since
                // NavHost only has statusBarsPadding to let main screen list have
                // inset at the bottom with WindowInsetsSides.Bottom
              Column(Modifier.navigationBarsPadding()) {
                  //            
  • Related