Search code examples
androidandroid-jetpack-composeandroid-jetpack

Compose stops after function


I want to have two tables below each other in my app and I used this code as a template for a table. The problem is that when I call the table component, everything after it won't be executed. It doesn't show any error or anything in logcat so I have no idea what is causing it.

Main:

Column {
    MyTable(someData = mylist) // will show

    
    Text(text = "Hello") // won't show
    MyTable(someData = mylist) // won't show
}

MyTable.kt

data class Cell(
    val name: String,
    val weight: Float
)

@Composable
fun RowScope.TableCell(...) { /* same as in the linked code */ }

@Composable
fun MyTable(data: List<Something>) {
    val columns = listOf(
        Cell("a", .25f),
        Cell("b", .25f),
        Cell("c", .25f),
        Cell("d", .25f)
    )

    LazyColumn(
        Modifier
            .fillMaxSize()
            .padding(16.dp)
    ) {
        item {
            Row {
                columns.forEach {
                    TableCell(
                        text = it.name,
                        weight = it.weight
                    )
                }
            }
        }

        itemsIndexed(data) { ind, item ->
            Row(Modifier.fillMaxWidth()) {
                TableCell(
                    text = item.somenumber.toString(),
                    weight = columns[0].weight
                )

                TableCell(
                    text = "Abc",
                    weight = columns[1].weight
                )

                TableCell(
                    text = item.somestring1,
                    weight = columns[2].weight
                )

                TableCell(
                    text = item.somestring2,
                    weight = columns[3].weight
                )
            }
        }
    }
}

Solution

  • As @Jakoss correctly pointed out, the first view with Modifier.fillMaxHeight(1f /* default value */) inside Column will take up all available space, so other views are not visible.

    The solution depends on how you expect your final layout to work.

    1. If you want to see both tables on the screen at the same time, and scroll each independently of the other, you can apply the Modifier.weight(1f) to each of them - this will make them the same size and fill height. This modifier is part of ColumnScope, so you need to pass it as a parameter of your MyTable:

      MyTable:

      @Composable
      fun MyTable(
          data: List<Something>
          modifier: Modifier,
      ) {
          // ..
      
          LazyColumn(
              modifier
                  .padding(16.dp)
          ) {
              // ..
      

      Main:

      Column {
          MyTable(
              someData = mylist,
              modifier = Modifier
                  .weight(1f)
          )
      
          Text(text = "Hello")
      
          MyTable(
              someData = mylist,
              modifier = Modifier
                  .weight(1f)
          )
      }
      
    2. The other case is if you want to have one scrollable table with two "subtables". In that case, you should have only one `LazyColumn', and both subtables as elements inside. Something like this:

      Main:

      LazyColumn {
          myTableItems(data = mylist)
          item {
              Text(text = "Hello")
          }
          myTableItems(data = mylist)
      }
      

      myTableItems:

      fun LazyListScope.myTableItems(data: List<Something>) {
          val columns = listOf(
              Cell("a", .25f),
              Cell("b", .25f),
              Cell("c", .25f),
              Cell("d", .25f)
          )
          item {
              Row {
                  columns.forEach {
                      TableCell(
                          text = it.name,
                          weight = it.weight
                      )
                  }
              }
          }
      
          itemsIndexed(data) { ind, item ->
              Row(Modifier.fillMaxWidth()) {
                  TableCell(
                      text = item.somenumber.toString(),
                      weight = columns[0].weight
                  )
                  // other cells
              }
          }
      }