5
votes

In the traditional view system, I handled responsiveness by using bias/guidelines/weights/wrap_content/avoiding hard coding dimensions/placing views relative to each other in Constraint Layout, using 'sdp' and 'ssp' etc.

How do I create responsive layouts with Jetpack Compose? I've been searching for info regarding it but unable to find.

Please help!

1
For example using: dimensionResource(id = R.dimen.xx)Gabriele Mariotti
@GabrieleMariotti, I had been using percentage (bias/weights/guidelines etc) in Constraint Layout to make sure my widgets occupied particular position in screen, as one of the ways to achieve responsiveness, as hardcoding the dimensions/position didn't work for responsiveness. Do I have to follow similar guidelines with Compose? Or are compose apps responsive even if I hardcode the dimensions/positions?Sparsh Dutta
What do you mean with responsive here? Compose relies on layouts that by default will use whatever available space.Gabriele Mariotti
Using linear layout weights had to be used to ensure responsiveness instead of providing margins. Is something similar to be done in compose while using Columns/Rows etc..?Sparsh Dutta
Yes, there is the weight modifier for exampleGabriele Mariotti

1 Answers

3
votes

Two things can help you build flexible and responsive layouts in compose.

1 - Use the Weight modifier in Row and Column

A composable size is defined by the content it’s wrapping by default. You can set a composable size to be flexible within its parent. Let’s take a Row that contains two two Box composables. The first box is given twice the weight of the second, so it's given twice the width. Since the Row is 210.dp wide, the first Box is 140.dp wide, and the second is 70.dp:

@Composable
fun FlexibleComposable() {
    Row(Modifier.width(210.dp)) {
        Box(Modifier.weight(2f).height(50.dp).background(Color.Blue))
        Box(Modifier.weight(1f).height(50.dp).background(Color.Red))
    }
}

This results in:

enter image description here

2 - Use BoxWithConstraints

In order to know the constraints coming from the parent and design the layout accordingly, you can use a BoxWithConstraints. The measurement constraints can be found in the scope of the content lambda. You can use these measurement constraints to compose different layouts for different screen configurations.

It lets you access properties such as the min/max height and width:

@Composable
fun WithConstraintsComposable() {
    BoxWithConstraints {
        Text("My minHeight is $minHeight while my maxWidth is $maxWidth")
    }
}

Example usage:

BoxWithConstraints {
    val rectangleHeight = 100.dp
    if (maxHeight < rectangleHeight * 2) {
        Box(Modifier.size(50.dp, rectangleHeight).background(Color.Blue))
    } else {
        Column {
            Box(Modifier.size(50.dp, rectangleHeight).background(Color.Blue))
            Box(Modifier.size(50.dp, rectangleHeight).background(Color.Gray))
        }
    }
}