šØāš»Constraint Layout in Jetpack Compose with Examples
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šā¦
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.
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*().
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() .
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.
Letās add the gradient background (Guideline)
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)
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.
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)
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šš¤.