Blog Infos
Author
Published
Topics
,
Author
Published

Jetpack Compose provides modifiers to change the look and feel of the Composable. But the order in which modifiers are provided affects the outcome of the Composable.

In XML based approach these values were provided via properties in XML and it didn’t matter in which order you provide But in Compose it does matter.

In order to understand this Let’s take an example.

In the example below we are showing a Box with chain of modifiers as mentioned below.

Box(
Modifier
.border(1.dp, Color.Red)
.padding(10.dp)
.size(40.dp)
.background(Color.Green)
)

The Output of the above code via Composable Preview window

Now Let’s take the same example code and just change the order of the modifiers by swapping border modifier with padding modifier, as shown below.

Box(
Modifier
.padding(10.dp)
.border(1.dp, Color.Red)
.size(40.dp)
.background(Color.Green)
)

The output of above code will be different as shown below i.e the red bordered Square is now around the green box

We just saw changing the chain of modifiers to rearrange the same modifiers in different order impacts the output of the composable.

How does the order of modifiers affect the outcome?

To understand, we need to see Under The Hood how Compose UI is drawn from Composable functions.

Compose transform Data into UI via three phases as shown below

  • Composition —What to show?: Compose Runtime goes through Composable functions, sees what has to be shown and builds a tree structure that represents UI. Each node in that structure is a Layout Node which contains information for the next phase in the process.
  • Layout — Where to show?: This phase takes tree structure as input , traverses it, going through each node and its children measuring the widthheight and x/y coordinates of its children and eventually of its own node in a 2D Space.
  • Drawing — How to render?: This traverses the tree structure node by node and draws each node on 2D screen pixel by pixel.

Layout and Drawing Phases

Layout phase determines the placement x&y and size width & height of each layout and its children using modifiers and constraints.

Drawing Phase draws the layout and applies modifiers that need to apply in the Drawing phase.

Some of the modifiers have an impact in Drawing phase such as border , clip modifiers are related to drawing and they get applied only in Drawing phase of the Composition. These modifiers are applied in the chain of modifiers from Right to Left .

Similarly some modifiers have an impact in Layout phase. In general all of those modifiers which can impact the size and the placement of UI elements are applied in Layout phase such as size , padding , fillMaxSize , sizeIn , wrapContentSize , requiredSize etc. These modifiers are applied in the chain of modifiers from Left to Right.

So to understand the full picture how modifiers are applied together we will look at these two phases together.

Before moving forward one more point to keep in mind that in Layout phase constraints and modifiers are applied together to decide the final size and placement of each UI element.

Such as in Layout phase each node passes its constraints to its children nodes restricting them to not exceed the boundaries out of those constraints then children nodes decide its size within those constraints and pass on updated constraints to their children further so on and at the end parent node decides its size and placement once all of its children are decided.

Let’s see now how modifiers are applied via a diagram, We will take the code example as shown above in the first example.

Box(
Modifier
.border(1.dp, Color.Red)
.padding(10.dp)
.size(40.dp)
.background(Color.Green)
)

Below diagram shows how modifiers get applied.

In the diagram each arrow is labeled with number 1, 2,3 etc showing the order of modifiers applied.

Layout Phase: Represented with top arrows going from Left to Right

Drawing Phase: Represented with bottom arrows going from Right to Left

As mentioned before the modifiers which impact the size and placement of the UI element are applied from Left to Right which are mentioned in the diagram with the top arrows going from Left to Right numbered 1, 2 and 3 as these modifiers impact the size and placement.

The bottom arrows 4 and 6 show modifiers which are applied during the Drawing phase so they are applied from Right to Left which are mentioned with the bottom arrows going from Right to Left .

Each top arrow in Layout phase which are labeled 1, 2 and 3 have constraints which are passed from Left to Right keeping the next modifier not to exceed the provided constraints coming from the previous modifier. On every step the constraints get updated due to modifiers and updated constraints are then passed to the next modifiers and so on.

Let’s see the diagram for the 2nd code example.

Box(
Modifier
.padding(10.dp)
.border(1.dp, Color.Red)
.size(40.dp)
.background(Color.Green)
)

Let’s see how UI is drawn.

We can see the final size of the Box is finalised to 40dp and inner green box size is now reduced to 20dp due to 10dp padding applied on both sides after size modifier.

Let’s see further some other modifiers how they impact.

E.g let’s add clickable modifier in the start and end of the chain of modifiers around a Box.

Adding clickable at the start of the chain of modifiers .

Box(
Modifier
.clickable { }
.border(1.dp, Color.Red)
.size(40.dp)
.padding(10.dp)
.background(Color.Green)
)

Let’s see the tap effect.

We can see that it makes the whole area as tappable as we wanted.

But let’s now move the clickable modifier to the end of the same chain of modifiers as below.

Box(
Modifier
.border(1.dp, Color.Red)
.size(40.dp)
.padding(10.dp)
.background(Color.Green)
.clickable { }
)

And the tap effect looks like this below.

Now only the inner green box is tappable rather than the whole Box .

Summary

  • Compose requires a shift in mental model in building look and feel from previous XML based approach to new Compose based UI.
  • Composition is split into three phases ComposeLayout and Drawing
  • The order of modifiers matters it impacts the outcome of the UI look and feel.
  • Modifiers which affect the size and placement of the UI element are applied first and from Left to Right such modifiers are like sizepaddingrequiredSize and so on. These modifiers are applied during Layout phase of composition.
  • Modifiers which do not affect the size and placement are applied from Right to Left such modifiers are like clipborderclickable etc These Modifiers are applied during the Drawing phase of Composition.

Source

Hope it was helpful.

This article was previously published on proandroiddev.com

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

, ,

Migrating to Jetpack Compose – an interop love story

Most of you are familiar with Jetpack Compose and its benefits. If you’re able to start anew and create a Compose-only app, you’re on the right track. But this talk might not be for you…
Watch Video

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer for Jetpack Compose
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engin ...
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer f ...
Google

Jobs

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
It’s one of the common UX across apps to provide swipe to dismiss so…
READ MORE
blog
In this part of our series on introducing Jetpack Compose into an existing project,…
READ MORE
blog
In the world of Jetpack Compose, where designing reusable and customizable UI components is…
READ MORE
blog

How to animate BottomSheet content using Jetpack Compose

Early this year I started a new pet project for listening to random radio…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu