Reputation: 9073
So I am trying to create a Chess Board using JetPack compose & have managed to draw the layout a bit. But, Now I have issue that I want the board square to have a equal height as width. I want it to be perfect square.
Note: I don't want to give any fixed width or height. I want to fit squares in the screen's width & then each square's height should be as much as the width.
What I have tried:
@ExperimentalFoundationApi
class PlayGameActivity : BaseActivity() {
val darkSquare = Color(0xFF779556)
val lightSquare = Color(0xFFEBECD0)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Column {
Board()
}
}
}
@Composable
fun Board() {
Column {
for (i in 0 until 8) {
Row {
for (j in 0 until 8) {
val isLightSquare = i % 2 == j % 2
val squareColor = if (isLightSquare) lightSquare else darkSquare
Box(
modifier = Modifier
.weight(1f)
.background(squareColor)
) {
Text(text = "${i + j}")
}
}
}
}
}
}
}
It gives me following result:
What I expect it to look like:
Any Idea how I can calculate width & set it same as width of the square?
Upvotes: 28
Views: 25024
Reputation: 29260
A simpler solution is to set the aspectRatio
attribute on your modifier:
@Composable
fun Board() {
Column {
for (i in 0 until 8) {
Row {
for (j in 0 until 8) {
val isLightSquare = i % 2 == j % 2
val squareColor = if (isLightSquare) lightSquare else darkSquare
Box(
modifier = Modifier
.weight(1f)
.aspectRatio(1f)
.background(squareColor)
) {
Text(text = "${i + j}")
}
}
}
}
}
}
Upvotes: 75
Reputation: 363439
You can use the layout
modifier to adapt the dimension of the each Box
.
Something like:
Column {
for (i in 0 until 8) {
Row {
for (j in 0 until 8) {
val isLightSquare = i % 2 == j % 2
val squareColor = if (isLightSquare) Yellow else Red
Box(
modifier = Modifier
.weight(1f)
.background(squareColor)
.layout(){ measurable, constraints ->
// Measure the composable
val placeable = measurable.measure(constraints)
//get the current dimension to assign width=height
val currentWidth = placeable.width
//assign the dimension and the position
layout(currentWidth, currentWidth) {
// Where the composable gets placed
placeable.placeRelative(0, 0)
}
}
,
) {
Text(text = "${i + j}")
}
}
}
}
}
In your case, if you know the board width you can also use something like:
var size by remember { mutableStateOf (Size.Zero) }
val width = with(LocalDensity.current){
(size.width/8).toDp()
}
Column(
Modifier.fillMaxSize()
.onGloballyPositioned { coordinates ->
size = coordinates.size.toSize()
}) {
//...
Box(
modifier = Modifier
.size(
width = width,
height = width,
)
.background(squareColor)
,
)
//...
}
Upvotes: 12