I'm using Kotlin with Jetpack Compose for an Android app and I'm facing a problem that I'm struggling to solve. This is the result when I run the code below with COLUMNS
equals to 7
:
This is the result with COLUMNS
equals to 8
:
As you can see some times the columns are not all the same height (you can see the black background). How to solve this problem?
I tested the code below on 3 different devices and these are some the results:
With COLUMNS = 7
:
Google Pixel 2
: the first column is shorter than the others (first image)Google Pixel C
: the last 4 columns are shorter than the othersXiaomi Mi A2 Lite
: the first column is shorter than the othersWith COLUMNS = 8
Google Pixel 2
: the first 4 columns are shorter than the othersGoogle Pixel C
: the first 4 columns are shorter than the othersXiaomi Mi A2 Lite
: the first 4 columns are shorter than the othersI simplified the code as much as possible to find the problem but still I can't find it:
package com.example.test
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import com.example.test.ui.theme.TestTheme
import kotlin.random.Random
const val COLUMNS = 11
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TestTheme {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Table(modifier = Modifier.fillMaxWidth(.9f))
}
}
}
}
}
@Composable
fun Table(modifier: Modifier = Modifier) {
Row(modifier = modifier.background(Color.Black)) {
for (columnIndex in 0 until COLUMNS) {
Column(
modifier = Modifier
.background(Color(Random.nextInt(256), Random.nextInt(256), Random.nextInt(256)))
.weight(1f)
) {
for (rowIndex in 0 until 5) {
Box(modifier = Modifier.aspectRatio(1f)) {
Box(modifier = Modifier.fillMaxSize()) {
// TODO
}
}
}
}
}
}
}
Because of rounding. You want to split some horizontal space W
evenly between N
columns. And when W mod N != 0
, some columns will be 1 pixel narrower than the rest. The number of narrower columns depends on the device width and number of columns, as you realized.
You then put 5 boxes with aspectRatio(1f)
in each column, meaning the height of the column is 5 times its width, so the height difference is 5 pixels.