Android Jetpack Compose contains width()
, height()
and size()
layout modifiers as well as requiredWidth()
, requiredHeight()
and requiredSize()
. What is the difference between these two sets of modifiers? Should I use plain modifiers or required ones?
The difference is that plain modifiers like width() take into account layout Constraints while required modifiers like requiredWidth() ignore them. You can think of constrains as min/max width/height of a measured element. To better understand how layout modifiers and constraints work take a look at this post.
Let's see an example of width modifier, height and size behave the same way.
@Composable
fun WidthModifierExample() {
val columnWidth = 200.dp
Column(
modifier = Modifier
.width(columnWidth)
.border(1.dp, Color.Gray)
) {
Text(
text = "requiredWidth = parent - 50",
modifier = Modifier
.requiredWidth(columnWidth - 50.dp)
.background(Color.LightGray)
)
Text(
text = "requiredWidth = parent + 50",
modifier = Modifier
.requiredWidth(columnWidth + 50.dp)
.background(Color.LightGray)
)
Text(
text = "width = parent - 50",
modifier = Modifier
.width(columnWidth - 50.dp)
.background(Color.LightGray),
)
Text(
text = "width = parent + 50",
modifier = Modifier
.width(columnWidth + 50.dp)
.background(Color.LightGray)
)
}
}
The dark gray border is the column boundaries, the texts background is light gray. Modifier.width(200.dp)
is applied to the column so it receives minWidth = 200dp; maxWidth = 200dp
constraints. The Column layout doesn't limit its children minimum width so each child gets minWidth = 0; maxWidth = 200dp
constraints. The first two texts use requiredWidth()
modifier which ignores this constraints so the second text is wider than the parent column. The last text width is reduced to 200dp
according to the maxWidth = 200dp
constraint because it uses width()
modifier instead.
In the example above only the maximum width of the texts was constrained. Lets see another example where the minimum width is constrained as well:
@Composable
fun WidthModifierExample() {
Column(
modifier = Modifier.border(1.dp, Color.Gray)
) {
val minWidth = 140
val maxWidth = 200
val widthDescriptions = arrayOf(
WidthDescription(minWidth - 50, "min - 50"),
WidthDescription((minWidth + maxWidth) / 2, "between min and max"),
WidthDescription(maxWidth + 50, "max + 50")
)
for (widthDescription in widthDescriptions) {
Text(
text = "requiredWidth = ${widthDescription.description}",
modifier = Modifier
.border(.5.dp, Color.Red)
.widthIn(minWidth.dp, maxWidth.dp)
.background(Color.LightGray)
.requiredWidth(widthDescription.width.dp)
)
}
for (widthDescription in widthDescriptions) {
Text(
text = "width = ${widthDescription.description}",
modifier = Modifier
.border(.5.dp, Color.Red)
.widthIn(minWidth.dp, maxWidth.dp)
.background(Color.LightGray)
.width(widthDescription.width.dp)
)
}
}
}
data class WidthDescription(
val width: Int,
val description: String
)
In this case the Column()
doesn't add any constraints but each child Text()
is wrapped in widthIn() modifier which adds its own constrains. The light gray background shows the texts size while the red border shows dimensions of the resulting element. As you can see requiredWidth()
modifier of the first three texts ignores the outer constrains, as the result the element width and its child Text()
width might be different. The last three texts uses width()
modifier which takes into account the constrains so Text()
width is always matches the resulting element.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With