What is a table?
What are Rows and Columns?
How to create a table in Jetpack Compose?
Game using Jetpack Compose?
Let's build a table in Jetpack Compose
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).
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.
Row(modifier = Modifier.fillMaxWidth()) {....}- Each row is created using a Row that spans the entire screen width.
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).
- 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
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
)
}
}
}
}
}
}
}
}

