If you’ve been doing Android development for some time, you’ve probably come across issues with ListView. For most uses ListView is great. It handles everything you need and it is efficient; however, there are times when ListView doesn’t do everything you want. For instance, animating views within ListView has a lot of challenges and there isn’t a good way to change how the items are laid out.
To solve these issues, RecyclerView was created. Its name is a reference to the process of view recycling that we’ve discussed previously where a view that goes off screen can then be reused for a new view coming onto the screen. RecyclerView works similarly to ListView but with a more modular architecture. For instance, instead of assuming that you want your items vertically stacked, you supply a layout manager that handles determine how to lay out the items. Given that RecyclerView can do everything that ListView can, you might be wondering when you should still use ListView. The simple answer is to use ListView unless you encounter one of its limitations. Contrary to some opinions, ListView isn’t dead and you shouldn’t change all your ListViews over to RecyclerViews without reason. If you find that ListView doesn’t work for you, that’s the time to switch over to RecyclerView.
If you want a good starting point for playing around with RecyclerView, check out the sample. From Android Studio, open the File menu and select Import Sample and then type “Recycler View” in the search box. This will let you quickly set up a project that uses RecyclerView so that you can see how it works and experiment with it.
To tell RecyclerView how to arrange the views, you need a layout manager. It’s responsible for measuring and positioning views as well as handling the view recycling policy. Fortunately, there are some built in ones for the typical use cases. You’ll commonly use LinearLayoutManager, which can give you a ListView-like display but also supports horizontal arrangement. You may also use GridLayoutManager or StaggeredGridLayoutManager for times when you want grids of items rather than just rows or columns.
Like ListView, RecyclerView uses an adapter to supply its views, but it works a little differently (also note that it’s RecyclerView.Adapter rather than android.widget.Adapter). You commonly have to use the view holder pattern with adapters for ListView as described earlier in the chapter to avoid repeated calls to findViewById, but that pattern is built in to RecyclerView with an actual ViewHolder class. Rather than the getView method, this adapter has two methods. First, onCreateViewHolder is expected to create any views that are necessary, but it returns a new ViewHolder instance that references those views. Second, onBindViewHolder is expected to set all the views up for a given position using the ViewHolder instance.
Note that a key difference between AdapterView and RecyclerView is how you listen to clicks. Rather than assigning a single onItemClickListener, RecyclerView just uses the regular onClickListener and related classes. Typically any necessary listeners are set in onCreateViewHolder and the position or object(s) they care about are updated in onBindViewHolder.
Whenever the state of the RecyclerView changes, it needs to know how to animate the change and that’s where the ItemAnimator abstract class comes in. A concrete implementation allows you to control the animations that are used to visualize these changes, so that your users can easily understand what happened. By default, RecyclerView uses the aptly named DefaultItemAnimator, but you can provide a custom implementation to precisely control the behavior.
RecyclerView has one more trick up its sleeve and that’s the concept of item decoration, which is based on the ItemDecoration abstract class. The idea is simple: sometimes you need to draw more than just the views that are displaying your data. For instance, you might draw dividers between items or visually group a section of items. ItemDecoration has both onDraw and onDrawOver methods. The former draws before the views are drawn (such as for backgrounds) and the latter draws after (meaning it draws in front of them). You can add multiple ItemDecoration implementations to your RecyclerView to get the effect you want, but you don’t have to use any.
One additional feature ItemDecoration has is the ability to modify the position of views. By overriding getItemOffsets, you can adjust positions as needed, which allows you to manipulate the display in powerful ways such as visually clustering content based on proximity or spacing.