Customize Layout Using Measured Policy
So, one day, I’m having a problem with constructing my compose layout. I want to make a lazy row layout that has a view all item at the end of the scrolled layout. The layout looks like this :
It looks good and normal, but the problem is view all layout. My expectation is that it should be at the center of this row, but it actually at the top. This is view all code :
I already add verticalArrangement to the column so that the view inside it can be centered. But it didn’t go as expected.
At this point, I actually quite confuse as to why the view all layout cannot be centered. Then I think, maybe I need to change the parent vertical alignment instead of its child. So I try to change the parent, which is LazyRow, verticalAlignment to CenterVertically.
The result is like this :
The view all is aligned center finally!! This looks good, but wait!! Let’s look more carefully :
The layout is now a bit broken. Because we align the LazyRow itself, all the layout inside it will be aligned center vertically. And this actually create a weird behavior if we have uneven layout. Like the layout of Jalak Bali image that have more height then Gajah Sumatra image. Gajah Sumatra image is pushed to center following the image before it that has more height than it. So I think that this solution is not the right solution. But now, what should I do to make view all align center? Because I’m out of idea, I open layout inspector to see if I can get any clues. And I found out something :
The boundaries of the view all’s layout looks like it is wrapping its child layout. But I clearly use fillMaxHeight for its modifier. I thought that it will fill up the height of its parent which is LazyRow, but it seems that it doesn’t work like that.
Since I already tried many things to solve this problem, but I didn’t found any proper solution. And then I somehow think, why not measure it by myself? That’s why I try to use Layout and customize its MeasurePolicy.
So what is Layout and MeasurePolicy?
Layoutis the main core component for layout. It can be used to measure and position zero or more layout children.
It’s a way to create custom layout, Layout will be the base and MeasurePolicy will be the one that calculate the layout measurement.
The idea is simple, I want to get the previous item’s height so that I can measure the placement of View All item based on previous item’s height.
The measurement is simple, we need to measure the previous item height divided by two minus View All height divided by two. After measuring the height, I put the height in placeable.place() as y. And don’t forget to remove the verticalAlignment from LazyRow. The full code is here :
And… It works great!! The item with image looks good and the View All item is also placed in center vertically.
I think that’s all for my experience handling Layout with compose. Actually there are many things that still in question for me. Like, why is View All boundaries seems to be wrap its content and not in full height following its parent height? And I think this is what makes VerticalAlignment on View All Column is not working. And I think that this is the best solution that I can came out with for now. There are many challenging scenario when you use something new like Compose. But don’t give up and keep trying, because this is what make it interesting.