Create compose custom layout-”Easier than you think “

Sametgundogmus
Teknasyon Engineering

--

Rewrite the Rules with Jetpack Compose Custom Layout!

We are already familiar with the concept of ‘Custom Layout’ (or ‘Custom View’) from the times when we created UI with XML or View Classes. In this article, we will talk about how we can create a customized layout in an application where we develop the UI layer with Jetpack Compose.

Why is it necessary or when do we need to create a custom layout ? 🤔

Sometimes we need to create such a component that we cannot or should not create this component with existing Jetpack Compose equipment (Box, Column, Row etc.) . The reason for this may be the animations in the component, the sensitivity in measurement and size calculation, or it may be to create a more readable and manageable structure.

The image below, -whose code we will write later in the article- can be a simple example of these components. ⬇️

MyDearStairColumn : Items added start from where the previous item ends vertically and horizontally.

Let’s Get Introduced to Custom Layout Basics by Proceeding Through Our Example Step by Step 🕺

When creating a custom layout, we need to use the ‘Layout’ composable. This composable takes 3 parameters, these are; ‘modifier’, ‘content’ and ‘measurePolicy’.

created with https://app.codeimage.dev/
  • modifier’: As usual, it specifies the properties of ‘MyDearStairColumn’ such as how it will be positioned on the screen, its dimensions, and its background color.
  • content’: Other composable specifying the content of ‘MyDearStairColumn’.

As you can see, we usually take the first 2 parameters as external parameters and set them to the ‘Layout’ without manipulating them.

The third parameter, “measurePolicy”, is the parameter we will focus on more because we will handle the size and positioning logic of the child elements (“Button1”, “Button2”..) of our custom layout through this parameter.

Since “measurePolicy” is an function interface we can also use it like this. It has a measure function that we call it as a trailing lambda and it receives two parameters: measurables and constraints.

From this point on, what we need to do is according to the rules of the component we want to reveal at the end of the day; calculating the sizes and positions of child items.

⬆️ To do this, first of all, to have a clearer idea about the dimensions of our child items; we convert the ‘measurables’ parameter into a ‘List<Placeable>’ object as shown in the image.

⬆️ With the help of this list, we calculate the total width and height information of our custom layout.

Then we can call layout method. This function is different from layout function with the capital L. By giving width and height to this function we are telling how large our layout can be. Then this layout gives us placement scope, which we can call place function on our placeables. We can loop on our placeables and place all of them. This function need coordinates. We must calculate x and y coordinates based on our needs.

Now let’s finalize our example by making our actual calculations.

The total width value of our layout; it should be the sum of the widths of the child items inside (as long as it does not exceed the maxWidth). The total height should be the sum of the heights of all the items in it.

Finally, what we need to do is to draw our child items with a loop — by calculating their starting positions horizontally (X) and vertically (Y) (placeable.place(x, y)).

Our final code looks like this ;

We can show the ‘usage example’ as follows ;

Output is :

You can access the code on my Github

I would like to thank Saman Sattari for sharing his experience and support in writing this article.

If you have any feedback or suggestions, you can let me know on Linkedin 💬

I hope it wasn’t boring, thank you for reading 💛 💚

--

--