9

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!

Sparsh Dutta
  • 2,450
  • 4
  • 27
  • 54
  • 1
    For example using: dimensionResource(id = R.dimen.xx) – Gabriele Mariotti Apr 19 '21 at 07:24
  • @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 Apr 19 '21 at 07:34
  • What do you mean with *responsive* here? Compose relies on layouts that by default will use whatever available space. – Gabriele Mariotti Apr 19 '21 at 07:37
  • 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 Apr 19 '21 at 07:38
  • Yes, there is the weight modifier for example – Gabriele Mariotti Apr 19 '21 at 07:39
  • @GabrieleMariotti With 'responsive' I mean a layout that adjusts to different screen sizes. In other words my layout will look same on small, medium and large size phones and tabs etc. – Sparsh Dutta Apr 19 '21 at 07:39
  • Are compose layouts responsive by default? – Sparsh Dutta Apr 19 '21 at 07:40

1 Answers1

9

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))
        }
    }
}
ameencarpenter
  • 2,059
  • 1
  • 11
  • 20