šŸ‘Øā€šŸ’»Constraint Layout in Jetpack Compose with Examples

Photo by AmƩlie Mourichon on Unsplash

Hey, letā€™s assume you have a task that designs a screen such as the below screen ā¬‡. The design has a profile image, notification icon, greeting message with a dynamic user name -user name can be long or short or multiple keywords-, some services, some appointment items etc.

How do you design this in Jetpack Composeā“ Need lots of nested rows and columns? Isnā€™t thereā“ Keep readingšŸ˜Žā€¦

Inspired by Rajesh Rathods design

First of all, I am so sorry for situation in Rafah, Gaza, Palestine. Letā€™s call for an immediate ceasefire and urge the allowance of humanitarian aid. Let Palestine be free from genocide.

United Nations News (May 13, ā€˜24)

Introduction

Hi folks šŸ‘‹. In this article, weā€™ll talk about using ConstraintLayout in Jetpack Compose. This article assumes you are familiar with ConstraintLayout and Jetpack Compose. I will summarize a little bit. Then I will show the capabilities of ConstraintLayout that we can use in Jetpack Compose with examples.

We will design the above screen without any Row and Column layouts as possible.

Letā€™s start ā˜•.

ConstraintLayout is a layout that allows you to place composables relative to other composables on the screen. It is an alternative to using multiple nested Row, Column, Box and custom layout elements. ConstraintLayout is useful when implementing larger layouts with more complicated alignment requirements. [SOURCE]

ConstraintLayout in Jetpack Compose

By using id in XML we can create references for views. We do that in the compose via createRefs() or createRefFor(). By these DSL functions, we can create a reference for each composable on the screen. Keep in mind that createRefs() can take 16 components. If you need more you can create with new createRefs() function. You can see examples of it in the github repo.

We can specify constraints for a reference (composable) via constraintAs() modifier function.

ConstraintLayout supports guidelines, barriers and chains in Jetpack Compose. Letā€™s look them.

Guidelines

We can use guidelines vertically or horizontally. And we can specify itsā€™ positions as dp or as percentange. We can create a reference of a guideline via createGuidelineFrom*().

Creating guideline examples

Barriers

We can create a reference of a barrier via create*Barrier() such as createTopBarrier(), createBottomBarrier(), createEndBarrier(), createStartBarrier().

Chains

We can use chains vertically or horizontally. We can create a reference of a chain via create*Chain() .

Creating chain examples

Letā€™s Practice šŸ‘Øā€šŸ’»ā˜•

First of all, we need to add the dependency.

implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"

Before starting coding I want to visualize the constraints of the design. And I want to show which concepts of the Constraint Layout are used where and how. In this way, I want it to come to life more easily in your mind. Please look at the below images carefully.

Constraints of the design. Red: Guideline, Green:Chain, Blue:Barrier

Letā€™s add the gradient background (Guideline)

Adding the gradient background to the screen

1)Firstly we create a reference for the background via creaRefs() on line 1

4) Then we create a guideline nearly to the middle of the screen via createGuidelineFromTop(0.45f) on line 4. So now we can place some other references/composables relative to the center of the screen.

11) Then we specify the reference of the composable (Image) via Modifier.constrainAs(gradientBackground) on line 11. So now we can place some other references/composables relative to the gradientBackground reference. Then we write all the constraints in the constrainBlock.

12) We specify the top of the background will be relative to the top of the parent (constraintLayout) via X.linkTo(Y) on line 12. This is same as app:layout_constraintTop_toTopOf="parent"in the XML side.

15) We specify the bottom of the background will be relative to the center of the screen on line 15.

16) We make the composable fill to all areas provided by horizontal constraints via Dimension.fillToConstraints on line 16. This is same as android:layout_width="0dp"in the XML side. Line 17 is similar.

Letā€™s add profile and notification icons (Chain)

Profile icon and nofitication icon with Chain

Firstly we created references for our new composables on line 3. Then we created a chain for our composables on line 11. We set SpreadInside as the chain style in order to first and last composables are affixed to the constraints on each end of the chain. So we donā€™t need to specify where the profile picture icon starts (āŒ start.linkTo(startGuideline)) and we donā€™t need to specify where the notification icon ends (āŒend.linkTo(endGuideline)). And also thanks to the chain space of between composables will be calculate automatically. For instance, if we add new icons and refactor the chain as below we will see the icons distributed evenly.

Chain with more composables
Result of the chain with more composables

Letā€™s add greeting message and the image of doctor (Barrier)

Please note, I said username is dynamic. Imagine that we put the picture of the doctor at the end of the ā€œWelcome!ā€ message. When a long username comes in, the name will appear on the image. We donā€™t want to this. Letā€™s imagine we put end of ā€œUserNameā€ text. When a short username comes in, the ā€œWelcome!ā€ message will appear on the image. This will be also for asking message. So we need a container for dynamic content. This is where the barrier comes into play. (For more detail you can watch 2-minute video of this video)

Barrier example with dynamic content

Firstly we created an endBarrier via createEndBarrier() function and passed references of the composables on lines 2,3,4. In order to make the image size change dynamically we set the start constraint of it to barrier in the line 32. You can see in the above screenshots that when a short name comes the image is wider and when a long name comes the image is less wide.

Apart from the barrier I want to add that we placed to bottom of the image to horizontalCenterGuideline on line 34. Then we make the image fill to all areas provided by constraints via Dimension.fillToConstraints line 35,36. Also we can give a margin when using linkTo() such as line 43.

The rest of the screen is as follows.

I used the same things I mentioned above on the rest of the screen. I generally used the linkTo() function. But you can also use anything else anywhere. For example, I used the linkTo() function for the text ā€œAppointmentā€ and ā€œSee Allā€. But we can also use chains like profile and notification icon. You can see the rest of the screen in the repo below ā­šŸŒŸ.

ā—āš ļø In the repo I didnā€™t seperate composableā€™s and I didnā€™t use row, column. The whole screen in one file. Keep in mind that, this is not a good practice for real life. This is a just demonstration for usage of ConstraintLayout. We should seperate our composables in order to resusablitiy, readability, testability etc ā—āš ļø.

šŸ”š šŸ’š šŸ‘ Conclusion

In this article, we examined using ConstraintLayout in Jetpack Compose. Thank you for reading šŸ‘. I hope it was useful. You can let me know by clapping the article šŸ‘. See you soon, stay safešŸ‘‹šŸ¤—.

Resources

--

--

Cengiz Toru (šŸ‡µšŸ‡ø #FreePalestineFromGenocide)
Huawei Developers

(šŸ‡µšŸ‡ø #FreePalestineFromGenocide šŸ‰) | Muslim, Computer Engineer & Android Developer @ Hepsiburada (NASDAQ: HEPS ) , ex; Huawei, T-Soft, Arneca