Scaling Layout
Last 2–3 days, I was motivated to share something on github. Actually, good UIs on apps motivates me to make it open source. Recently, I started to use Blinkist app and It actually one of the best apps that I recently used. As every developer does, I first looked at user interface of the app.
In Blinkist detail screen, there is a layout (has 2 action) that is anchored to appbar layout.When you scroll up, It moves up, round rate decreases and pins below the toolbar. I really like that animation and I motivated to write that code.
I am not going to explain all the code here. I just want to share steps that I took to create this library.
Be careful
- Layout shouldn’t move up and down internally. It should be done in CoordinatorLayout.Behavior<>.
- Initial radius should dynamic. So user may want to give a radius factor to layout.
- This is a wrapper layout. So covered layout in xml should be change when ScalingLayout is changed.
- User can give a margin to layout. So I should play with margins too.
Steps to create
1- I create a empty view which extends from FrameLayout.
2- I clip my layout with rounded corner. So created a Path first. Then apply it to canvas.
3- Calculate radius value in pixel (only attribute I take from outside is radiusFactor)
4- I calculate the layout width with current radius of layout. The width should decrease as the radius increases. Or vice versa.
5- As the radius increase, the margins must increase.
I will show you the code. It gives you more clear explanation.
/**
* Set radius will update layout radius
* Also layouts margins and width depend on
* radius. So If you update radius, your layout's width
* and margins will be updated.
*
* @param radius
*/
private void setRadius(float radius) {
if (radius < 0) {
return;
}
updateCurrentRadius(radius);
updateCurrentWidth(currentRadius);
updateCurrentMargins(currentRadius);
updateState(currentRadius);
getLayoutParams().width = currentWidth;
((ViewGroup.MarginLayoutParams) getLayoutParams())
.setMargins((int) currentMargins[0],
(int) currentMargins[1],
(int) currentMargins[2],
(int) currentMargins[3]);
requestLayout();
}
6- Created an animation for expand and collapse. My aim is updating layout with collapsing toolbar is scolled. But some developer may just want to expand and collapse.
7- Created a listener to notify about changes.
8- Created Custom behavior. I wanted to use it in coordinator layout. Just like in blinkist app.
Thats all.
I wanted to show you, creating UI is all about divide and conquer. Here is the result of my library.
If you want to support. You can fork and send PR.
Thanks for reading. Please don’t hesitate to comment.