Pretty scrolling and shaking animation in RecyclerView

Alex Maryin
3 min readJul 23, 2021

--

Photo by Artem Beliaikin on Unsplash

In my first published app SpaceX Times I wanted to feature pretty animation in RecyclerView: smooth scrolling to the next rocket launch and shaking it. Resulting animation is on the following gif:

Scrolling and shake item

But RecyclerView has no any simple method to do this from a box. Standard item animation of RecyclerView is using for other purposes: animate how to show item or hide one. As you see I already provided some arrive animation for the items. Also I didn’t find similar interpolation in standard Android animations.

To achieve desired result we have to write a custom animation and shaking interpolator. Let’s start.

At first, assign animation for showing item to ViewHolder in RecyclerView adapter. I use custom BaseAdapter and Visitor pattern to manage all kinds of ViewHolders together with DataBinding library, so I assigned animation to root layout of binding object in base method bind in the inner class DataViewHolder of BaseAdapter as following:

Then, let’s think about sequence of necessary actions to reach correct behaviour of our RecyclerView. Now it doesn’t matter how the scrolling is called on UI but suppose we observe a trigger Flow from our ViewModel and collect an item position to scroll:

As you see I invoke method addItemShaker of my recyclerView. But standard RecyclerView has no such method, where it comes from? Thanks to Kotlin’s class extensions we can add a custom method to extend RecyclerView class as we want:

fun RecyclerView.addItemShaker(position: Int) { // actions }

Sequence of animations has to be as following:

  1. Smooth scrolling to target position in list.
  2. Shaking of target item.

We could use standard method of RecyclerView to smooth scroll but it works not as I want: it stops as soon as target item appears either from bottom or top of the screen and I want to scroll item to top of the screen anyway. Android has a class called LinearSmoothScroller for the purpose of custom setup. All we need is to override getVerticalSnapPreference function and return type of snapping (SNAP_TO_START, SNAP_TO_END or SNAP_TO_ANY), also we have to assign position to targetPosition property of this class.

Now we can say to layout manager of RecyclerView: start smooth scrolling to target position with our custom scroller! But how to shake item after that? Easily! Add a custom listener to scrolling events and start shaking when scrolling has stopped, but don’t forget to remove your listener after shaking to prevent unwanted behaviour.

For shaking I use custom TimeInterpolator that is simple mathematical function from x (delta-time), I found it on StackOverflow. You can create your own functional interpolators on great site www.wolframalpha.com, enter your function to search field and get excellent graph immediately:

You can play with wave-frequency (ratio of pi) or decay-speed (power of e) to get other effects.

Now it’s time to combine all of elements together in our extension function:

There is a little trick with scroll to 10 pixels down at start. LayoutManager doesn’t start scroll and shaking doesn’t be invoke if your target item already on top of the screen. To force animations I have added this line which always leads to shaking.

That’s all, thank you for reading. Please add a comment if you like my variant to shake RecyclerView items. Get my SpaceX Times app on Google Play if you are SpaceX fan or explore a whole code on GitHub.

--

--

Alex Maryin
Alex Maryin

Written by Alex Maryin

My profession is lawyer, but I like programming for a whole my life. It started since 90's with ZX-spectrum, and now I fan of Kotlin, Python, Pascal & C++.

No responses yet