How to Create a Table in Jetpack Compose

How to Create a Table in Jetpack Compose

What is a table?

A table is a structured way to organize and display data in rows and columns. It is commonly used in UI design to present information clearly, such as in spreadsheets, databases, or app interfaces.

What are Rows and Columns?

Row- A horizontal layout contains all elements horizontally.
Column - A vertical layout contains all elements vertically .

How to create a table in Jetpack Compose?

In Jetpack Compose, there isn't a built-in Table component like in XML-based Android layouts, but you can create a table using Rows, Columns, and LazyColumn/LazyRow.

         In Jetpack Compose, Row and Column are layout composables used to arrange UI elements horizontally and vertically.

Let's build a table in Jetpack Compose

1. Table Data (List of Lists) 
val tableData = listOf(
listOf("Name", "Version number(s)", "Release date"),
listOf("Android 1.0", "1.0", "September 23, 2008"),
listOf("Android Cupcake", "1.5", "April 27, 2009"),
listOf("Android Donut", "Donut", "September 15, 2009")
)
  • The tableData is a list of lists, where each inner list represents a row in the table.
  • The first row is treated as the header row (bold text, larger font size).
2. LazyColumn for Scrolling
LazyColumn {
items(tableData.size) { rowIndex ->
  • LazyColumn is used instead of Column to enable efficient scrolling.
  • items(tableData.size) { rowIndex -> ... } iterates through each row in tableData.
3. Creating Table Rows
Row(modifier = Modifier.fillMaxWidth()) {....}
  • Each row is created using a Row that spans the entire screen width.
4. Creating Table Cells with OutlinedButton
Box(
modifier = Modifier
.weight(1f)
.height(100.dp)
.background(Color.White)
.padding(8.dp),
contentAlignment = Alignment.Center
) {
OutlinedButton(
onClick = { /*TODO*/ },
border = BorderStroke(width = 2.dp, color = Color.Cyan),
shape = RectangleShape
) {
Text(
text = cell,
fontSize = if (rowIndex == 0) 14.sp else 12.sp,
fontWeight = if (rowIndex == 0) FontWeight.Bold else FontWeight.Normal
)

}

}
  • Each cell is wrapped in a Box to apply background color, padding, and alignment.
  • The OutlinedButton:
  • Adds a cyan-colored border to each cell (acts as a grid line).
  • Uses RectangleShape to keep square edges (no rounded corners).
The Text inside the button:
  • Uses fontSize 14.sp for the header and 12.sp for other rows you can change according to your choice.
  • Uses FontWeight.Bold for header text to make it different from data in cells.

Full Code

Here is an example of table built in Jetpack Compose without using any third party library:-
package com.codingbihar.indianrailapp_booking

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp


@Composable
fun TableWithGridLines() {
val tableData = listOf(
listOf("Name", "Version number(s)", "Release date"),
listOf("Android 1.0", "1.0", "September 23, 2008"),
listOf("Android Cupcake", "1.5", "April 27, 2009"),
listOf("Android Donut", "Donut", "September 15, 2009")
)

Box(modifier = Modifier.systemBarsPadding()) {
LazyColumn {
items(tableData.size) { rowIndex ->
Row(modifier = Modifier.fillMaxWidth()) {
tableData[rowIndex].forEach { cell ->
Box(
modifier = Modifier
.weight(1f)
.wrapContentWidth()
.wrapContentHeight()
.background(Color.White)
.padding(8.dp),
contentAlignment = Alignment.Center
) {
OutlinedButton(
onClick = { /*TODO*/ },
border = BorderStroke(width = 2.dp, color = Color.Cyan),
shape = RectangleShape
) {
Text(
text = cell,
fontSize = if (rowIndex == 0) 14.sp else 12.sp,
fontWeight = if (rowIndex == 0) FontWeight.Bold else FontWeight.Normal
)

}

}

}

}
}
}
}
}

Other Possible Improvements you can do:-

✅ Clickable Buttons: Add functionality inside onClick.
✅ Dynamic Row Height: Use wrapContentHeight() instead of fixed 100.dp.
✅ Custom Cell Styling: Change background colors for alternate rows.

Final Project Output:

Previous Post Next Post

Contact Form