Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jetpack Compose - Order of Modifiers

Documentation says that Modifiers are applied from the left. But from this example it looks like they are applied from the right: First border and then padding because there is no space between text and border

Text("Hi there!", Modifier.padding(10.dp).border(2.dp, Color.Magenta))

enter image description here

like image 664
ivoronline Avatar asked Oct 05 '20 10:10

ivoronline


People also ask

What are modifiers in jetpack compose?

Modifiers allow you to decorate or augment a composable. Modifiers let you do these sorts of things: Change the composable's size, layout, behavior, and appearance. Add information, like accessibility labels.

When to Use remember jetpack compose?

remember can be used to store both mutable and immutable objects. Note: remember stores objects in the Composition, and forgets the object when the composable that called remember is removed from the Composition.

What is LazyColumn in jetpack compose?

A LazyColumn is a vertically scrolling list that only composes and lays out the currently visible items. It's similar to a Recyclerview in the classic Android View system.

How do you align text Center in jetpack compose?

To center align content of Column along horizontal axis in Android Compose, set horizontalAlignment parameter with the value of Alignment. CenterHorizontally . Also, we may fill the maximum width by the Column using Modifier. fillMaxWidth().


1 Answers

There’s Layouts in Jetpack Compose codelab containing Layout modifiers under the hood step which explains the modifier order, see "Order matters" section.

order matters when chaining modifiers as they're applied to the composable they modify from earlier to later, meaning that the measurement and layout of the modifiers on the left will affect the modifier on the right. The final size of the composable depends on all modifiers passed as a parameter. First, modifiers will update the constraints from left to right, and then, they return back the size from right to left.

To understand it better I'd recommend to figure out how layouts work in Compose. In short, padding() is a LayoutModifer, it takes in some constraints, measures its child size based on a projection of that constraints and places the child at some coordinates.

Let’s see an example:

Box(
  modifier = Modifier
    .border(1.dp, Color.Red)
    .size(32.dp)
    .padding(8.dp)
    .border(1.dp, Color.Blue)
)

And the result:

enter image description here

But let's swap the .size() and the .padding()

Box(
  modifier = Modifier
    .border(1.dp, Color.Red)
    .padding(8.dp)
    .size(32.dp)
    .border(1.dp, Color.Blue)
)

Now we have a different result:

enter image description here

I hope this sample helps you to figure out how the modifiers are applied.

One can expect that the red border should be the closest to the box since it was added first, so the order might seem reversed, but such an order has pros too. Let’s take a look at this composable:

@Composable
fun MyFancyButton(modifier: Modifier = Modifier) {
  Text(
    text = "Ok",
    modifier = modifier
      .clickable(onClick = { /*do something*/ })
      .background(Color.Blue, RoundedCornerShape(4.dp))
      .padding(8.dp)
  )
}

Just by moving the modifier to the arguments the composable allows its parents to add additional modifiers such as extra margin. Because the lastly added modifiers are the closest to the button, the border and the inner padding won’t be affected.

like image 134
Valeriy Katkov Avatar answered Oct 15 '22 22:10

Valeriy Katkov