Have you ever looked at animation as a developer, amazed at how beautiful and smooth looking at it is, only a few seconds later to realize the pain, agony, and worries you will suffer later when you start working on it?
That happened to me a few months ago. During one of my weekly Omvana sprint meetings, our designer showed us a whole new implementation of a horizontal scrolling wheel to change some soundtracks. I am telling you, the design blew our minds that day and the following days after.
The Early Thoughts
Enough of the chit-chat, diving into the real problem here; as complex as it might seem, it's pretty simple once you get into the hang of the mathematics behind it.
I won’t lie am not a genius that figured that entirely by himself. I had the subtle touches and the empty gaps completed from this excellent youtube video by Polly McEldowney. It filled in the gaps I needed to craft the full animation.
On to the point, then.
Well, long story short, that's the animation we had on hand, quite breathtaking, but after giving it a few thoughts, we can break it down into a straightforward concept:
It’s a recycler view with a circular layout manager plus a simple magnification to the item being snapped.
Yet, simple words won’t justify the animation's fanciness and smoothness off to the implementation.
Breaking this down and following Polly’s video earlier, I decided first to try and replicate a circular recycler view implementation first. There are quite a bit of maths behind it.
Recall Pythagoras theorem; it's going to be a great deal in today’s article; we need to know how much we need to shift the items from the x-axis and try to replicate a circular behavior the maths.
In simpler words, the Pythagoras theorem will help us determine how much y needed to be added on each item, according to its position from the center of the screen.
The breakdown of the math itself is simplified as much as I could in the following scratchpad. You can read it thoroughly and think that our main target is to get the y component (How much you need to push an item downwards) depending on how off you are from the center and towards the screen edges.
Translating this into actual implementation, right out of the bat, we need to create a new custom layout manager that can handle this arrangement, extend
RecyclerView.LayoutManager and implement the required methods.
After you create your custom layout manager, you need to override the following methods to allow your RecyclerView to scroll horizontally.
The horizontal offset gets added here if you need your RecyclerView to start at a point other than the start of the screen (As in the gif shown earlier, mid-screen, for instance), dx is the RecyclerView component to move an item from the beginning of the screen.
If you try to run the project in its current state, you will see an empty screen. And that’s alright because we didn’t instruct the layout manager how to draw items.
A much-needed function now that will define how we should draw items on the screen, let’s call this function fill. It will be responsible for adding the item in the RecyclerView and will allow you to define the needed offset for each item depending on its offset from the screen's edge.
Believe me, and we are almost there. We managed to add the items in the RecyclerView to add them in a ViewGroup. Still, we are yet to tell the RecyclerView why it should position the items to follow an arced animation accordingly.
One crucial function to focus on before we wrap up our implementation is the following function, the core idea behind the maths we calculated earlier, computing how much top offset you need to set for each item.
Finally, we need to wire all the pieces together, checking the RecyclerView documentation, we need to override one more function
onLayoutChildren for the first time the items are rendered on screen, to draw them following an arc pattern, you will need to call the fill function we implemented earlier after wiring it with
computeYComponent, also we need to call the same fill function in
scrollHorizontallyBy to keep the items in order while scrolling as well.
Eager to see the results? Wiring this layout manager into a RecyclerView and a simple adapter results in the following behavior.
To me, this was a pretty exciting experiment — combining mathematics with real-life UI implementation. Of course, we hadn’t had the exact implementation I showed earlier. With some UI touches in your RecyclerView and its adapter, you will be able to reach the same behavior you need.
Pretty excited to hear thoughts about this, hope this was a clear enough guide, and see you in an upcoming tech adventure, peace 😉