Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Jetpack Compose width / height / size modifier vs requiredWidth / requiredHeight / requiredSize

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?

like image 987
Valeriy Katkov Avatar asked Jan 18 '21 17:01

Valeriy Katkov


1 Answers

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)
        )
    }
}

enter image description here

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
)

enter image description here

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.

like image 81
Valeriy Katkov Avatar answered Sep 21 '22 20:09

Valeriy Katkov