Goodbye Listview — RecyclerView

TL;DR: DEMO

RecyclerView is a somewhat new view that came to substitute the ListView and GridView. From its documentation, you can see that it is a more efficient and advanced widget when compared to its predecessors, despite having many simplifications to support better animations and better arrangements of elements.

A more simple View, but more powerful.

In order to offer all those optimizations, Google decided to simplify the element. It may sound strange, but the RecyclerView has less responsibility than what the ListView had. In theory, the widget is simply a container that encapsulates a LayoutManager and an ItemAnimator, communicating with an Adapter, more precisely, a RecyclerView.Adapter.

Renan, I don't understand anything!

That's ok. Let's create a little example that will help illustrate how the widget works.

Diagram illustrating the components involved in the implementation of the RecyclerView(fonte)

Include Dependency

Let's start including the dependencies in our project. The RecyclerView was introduced with Android Lollipop, but it is distributed with the support library, making it possible to use in really old devices, such as Android 2.1.x and after.

Layout Manager

Different from the ListView, the RecyclerView does not have the responsibility to position the elements of the list, and, besides what its name may imply, it does not have the function to recycle the views either. All of those functionalities are provided by the LayoutManagers.

This separation of concerns allows the list widget to be used for different types of layout arrangements, for example, for vertical lists of items or even for displaying a grid layout.

Nowadays, you can use three types of LayoutManagers:

  • LinearLayoutManager: for the construction of vertical or horizontal lists;
  • GridLayoutManager: for the constructions of grids;
  • StaggeredGridLayoutManager: for the construction of grids whose items don't have a fixed size, creating a type of mosaic.

One example of usage of the LinearLayoutManager would be:

In case you are more interested in a grid layout, you only need to change the LayoutManager:

It is important to note that the GridLayoutManager constructor accepts the number of columns as the second parameter.

RecyclerView.Adapter

Forget about ArrayAdapter and/or BaseAdapter. If you intend to use the RecyclerView for constructing your app's lists, you will need an Adapter that extends from RecyclerView.Adapter. A big advantage of this new component is that you are now obligated to implement a ViewHolder. This one is a pattern promoted by Google that increases the performance of long lists by caching some views, avoiding some findViewById(…) operations, that, usually, have great impact on the smoothness of lists. When using ListView, some adjustments were necessary to implement this pattern.

Since the RecyclerView was developed with the ViewHolders' pattern in mind, its adapter already enforces the utilization of the latter, making our lives a little simpler.

In general, a RecyclerView.Adapter is composed of three main methods:

  • getItemCount: returns the number of elements presented on the list;
  • onCreateViewHolder: returns a new instance of a viewHolder;
  • onBindViewHolder: binds the data to each view of the list.

To exemplify, let's create a new adapter that will be responsible for listing a Model "Person".

Next, we create the famous ViewHolder. It consists of a simple static class, which extends from RecyclerView.ViewHolder and has references to all the views presented in one item of the list. So, it is important to make all the relevant findViewById(…) operations on its constructor.

Last, we need to connect the RecyclerView, presented in the Activity/Fragment, to the new adapter.

ItemAnimator

The last piece of this tutorial is about the component responsible for animating modifications that happen on the Adapter, like the removal or addition of items on the list.

For simplicity, the RecyclerView already has some default animations. To use them, we just need to substitute the famous notifyDataSetChanged method of the adapter for one of these:

  • notifyItemInserted(int position): to indicate the insertion of a new item at the indicated position;
  • notifyItemRemoved(int position): to indicate the removal of an item at the indicated position;

With this in mind, an example of addition of items on a list would be:

Demo

Finally, with all of this in place, you can have a list that looks and behaves like this:

References

images: http://abduzeedo.com/google-material-design-printed-kit-manual