Learn how to populate an empty RecyclerView grid using custom animations.

Series

Introduction

This is the second and final part in the series on how to apply a LayoutAnimation to a RecyclerView. Part 1 covered the case where the RecyclerView is used for a List and can be found here:

In Part 1 we showed how to populate an empty RecyclerView using custom animations. This was done using LayoutAnimation’s and it works well when the RecyclerView represents a list. This second part will focus on how the same method can be applied to grids as well, with a little tweaking.

The demo app project shown in this tutorial, containing examples for both Lists and Grids, is available here:

and an APK of the example project can be found here!

How is the grid case different?

First of everything from Part 1 will work fine on a grid, it won’t crash and the animations will be applied in the same way. However the end result of combining a LayoutAnimation with a RecyclerView that uses a GridLayoutManager gives the following end result:

LEFT: Grid with LayoutAnimation. RIGHT: What we want to achieve.

What happens is that the defined item animation is applied to each item based on it’s linear position in the grid (left to right, top to bottom) creating an awfully long enter animation. What we want is for item animations on different rows and columns to run simultaneous, and that way shorten the duration. Basically what we need is more control over the animation order and delays…

Sooo let’s get started

To fix the issue, we’ll be using a GridLayoutAnimation instead. It’s basically the same as a LayoutAnimation , but it makes it possible to define delays for rows and columns and also allows us to set a direction of the layout animation. This gives us more control over when a particular item starts it’s animation and makes it easier to run multiple item animations simultaneously. Start of by creating a file called grid_layout_animation_from_bottom.xml in res/anim/ and add the following:

This is what’s defined:

android:animation="@anim/item_animation_from_bottom”

Defines which animation to apply to each item in the layout.

Defines which animation to apply to each item in the layout. android:animationOrder="normal"

There are three types to choose from: normal , reverse and random . This allows to control in which order the content will be animated. Normal follows the order defined by direction and delays, Reverse is the same order as Normal but backwards, and Random…well Random is random order.

There are three types to choose from: , and . This allows to control in which order the content will be animated. Normal follows the order defined by and delays, Reverse is the same order as Normal but backwards, and Random…well Random is random order. android:columnDelay=”15%"

This is the delay that’s applied to each column and it’s defined as a percentage of the item animation duration.

This is the delay that’s applied to each column and it’s defined as a percentage of the item animation duration. android:rowDelay=”15%"

This is the delay that’s applied to each row and it’s defined as a percentage of the item animation duration.

This is the delay that’s applied to each row and it’s defined as a percentage of the item animation duration. android:direction=”top_to_bottom|left_to_right"

Defines in which direction the item animation is applied. In this case the animation will start in the top left corner and move to the right side and the bottom. If defined as top_to_bottom|right_to_left it would start in the top right corner and move to the left and the bottom.

For a GridLayoutAnimation the final delay used for an item is calculated by combining the row and column delays and the direction:

itemAnimationDuration = 300ms

rowDelay = 10% (30ms)

columnDelay = 10% (30ms)

direction = top_to_bottom|left_to_right



+------->

| +---+---+---+

| | 0 | 1 | 2 |

| +---+---+---+

V | 3 | 4 | 5 |

+---+---+---+

| 6 | 7 | 8 |

+---+---+---+ ROW COLUMN

0 = 0*30 + 0*30 = 0ms

1 = 0*30 + 1*30 = 30ms

2 = 0*30 + 2*30 = 60ms 3 = 1*30 + 0*30 = 30ms

4 = 1*30 + 1*30 = 60ms

5 = 1*30 + 2*30 = 90ms 6 = 2*30 + 0*30 = 60ms

7 = 2*30 + 1*30 = 90ms

8 = 2*30 + 2*30 = 120ms Final animation order by delay

+-----+-----+-----+

| 0 | 30 | 60 |

+-----+-----+-----+

| 30 | 60 | 90 |

+-----+-----+-----+

| 60 | 90 | 120 |

+-----+-----+-----+

Setting the row and column delays to the same value will apply the item animation symmetrically from the starting point defined by direction .

The item animation item_animation_from_bottom.xml is from Part 1 of this tutorial and is defined like this:

Applying the GridLayoutAnimation

The GridLayoutAnimation is applied in the same way as a normal LayoutAnimation, either programmatically or in XML:

However if you apply a GridLayoutAnimation to a standard RecyclerView you’ll get the following exception:

This happens because RecyclerView is a generic class that uses a LayoutManager to layout its children and has no knowledge of how the LayoutManager will position the children. Therefore, the RecyclerView doesn’t know if it should apply AnimationParameters for a list or a grid, so it defaults to parameters for a list. To fix this we need a custom RecyclerView, with knowledge about GridLayoutManager

Now the only thing left is to replace the RecyclerView with the new GridRecyclerView it in the XML:

Wrapping up

That’s all there is to it, using GridLayoutAnimation and the custom GridRecyclerView the desired effect is achieved:

LEFT: Grid with LayoutAnimation. RIGHT: Grid with GridLayoutAnimation.

The code for both parts in this tutorial is available on my Github account, here.