androidandroid-jetpack-compose

How do I create a table in Jetpack Compose?


I want to create table views, like the one below, to show the data I have.

A header Another header
First row
Second row

I tried using LazyVerticalGrid to achieve it but Jetpack Compose doesn’t allow me to put LazyVerticalGrid inside a vertically scrollable Column.

It’s been two days and I’m really out of ideas.


Solution

  • As far as I know, there's no built-in component to that. But it's actually easy to do it with LazyColumn and using the same weight for all lines of the same column.
    See this example:

    First, you can define a cell for your table:

    @Composable
    fun RowScope.TableCell(
        text: String,
        weight: Float
    ) {
        Text(
            text = text,
            Modifier
                .border(1.dp, Color.Black)
                .weight(weight)
                .padding(8.dp)
        )
    }
    

    Then you can use it to build your table:

    @Composable
    fun TableScreen() {
        // Just a fake data... a Pair of Int and String
        val tableData = (1..100).mapIndexed { index, item ->
            index to "Item $index" 
        }
        // Each cell of a column must have the same weight. 
        val column1Weight = .3f // 30%
        val column2Weight = .7f // 70%
        // The LazyColumn will be our table. Notice the use of the weights below
        LazyColumn(Modifier.fillMaxSize().padding(16.dp)) {
            // Here is the header
            item {
                Row(Modifier.background(Color.Gray)) {
                    TableCell(text = "Column 1", weight = column1Weight)
                    TableCell(text = "Column 2", weight = column2Weight)
                }
            }
            // Here are all the lines of your table.
            items(tableData) {
                val (id, text) = it
                Row(Modifier.fillMaxWidth()) {
                    TableCell(text = id.toString(), weight = column1Weight)
                    TableCell(text = text, weight = column2Weight)
                }
            }
        }
    }
    

    Here is the result:

    enter image description here