In this document
See also
Many apps need to display user-interface elements based on large data sets, or data that frequently changes. For example, a music app might need to display information about thousands of albums, but only a dozen of those albums might be on-screen at a time. If the app created UI widgets for each of those albums, the app would end up using a lot of memory and storage, potentially making the app slow and crash-prone. On the other hand, if the app created UI widgets each time a new album scrolled onto the screen and destroyed the widgets when it scrolled off, that would also cause the app to run slowly, since creating UI objects is a resource-intensive operation.
To address this common situation, the Android Support Library provides the
RecyclerView suite of objects.
RecyclerView and its associated classes and
interfaces help you to design and implement a
dynamic user interface that runs efficiently. You can use these classes as they
are, or customize them to suit your specific needs.
Dynamic View Structure
Under the RecyclerView model, several
different components work together to display your data. Some of these
components can be used in their unmodified form; for example, your app is
likely to use the RecyclerView class
directly. In other cases, we provide an abstract class, and your app is
expected to extend it; for example, every app that uses RecyclerView needs to define its own view holder,
which it does by extending the abstract RecyclerView.ViewHolder class.
The overall container for your dynamic user interface is a RecyclerView object. You add this object
to your activity's or fragment's layout; the RecyclerView, in turn, fills itself with smaller
views representing the individual items. The RecyclerView uses the layout manager you provide
to arrange the items. You can use one of our standard layout managers (such as
LinearLayoutManager or GridLayoutManager), or implement your own.
The individual items are represented by view holder objects. These objects
are instances of the class you define by extending RecyclerView.ViewHolder. Each view holder is in
charge of displaying a single item, and has its own view. For example, if a
RecyclerView is used to display a user's
music collection, each view holder might represent a single album. In this
case, the view holder's view might contain elements to display the album's
title and artwork, and might respond to clicks by playing or pausing that
album. The RecyclerView creates only as many
view holders as are needed to display the on-screen portion of the dynamic
content, plus a few extra. As the user scrolls through the list, the RecyclerView takes the off-screen views and rebinds
them to the data which is scrolling onto the screen.
The view holder objects are managed by an adapter, which you create by
extending the RecyclerView.Adapter abstract
class. The adapter creates view holders as needed. The adapter also binds the
view holders to their data. It does this by assigning the view holder to a
position, and calling the adapter's onBindViewHolder() method. That method uses the
view holder's position to determine what the contents should be. For example,
in the case of the music collection, the adapter might call onBindViewHolder() to assign a particular view holder to position 420. The
method would find out which album is in that spot in the list, and fill in the
view holder's widgets with the appropriate artwork and title.
The RecyclerView model does a lot of
optimization work so you don't have to:
-
When the view is first populated, it creates and binds some view holders on
either side of the list. For example, if the view is displaying albums 0
through 9, the
RecyclerViewcreates and binds those view holders, and might also create and bind the view holder for position 10. That way, if the user scrolls the list, the next element is ready to display. -
As the user scrolls the list, the
RecyclerViewcreates new view holders as necessary. It also saves the view holders which have scrolled off-screen, so they can be reused. If the user switches the direction they were scrolling, the view holders which were scrolled off the screen can be brought right back. On the other hand, if the user keeps scrolling in the same direction, the view holders which have been off-screen the longest can be rebound to new data. The view holder does not need to be created or have its view inflated; instead, the app just updates the view's contents to match the new item it was bound to. -
When the displayed items change, the app notifies the adapter by calling an
appropriate
RecyclerView.Adapter.notify…()method. The adapter's built-in code then rebinds just the affected items.
RecyclerView Workflow
To understand how RecyclerView works, it may
be helpful to follow a typical workflow. In this case, we assume that an app's
main activity uses a RecyclerView to manage a
simple list of text items, such as a list of names.
When the system creates the app's main activity, the system calls the
activity's onCreate() method. That method
takes a number of steps to set up the RecyclerView:
-
The
onCreate()method creates theRecyclerViewspecified by activity's layout:myRecyclerView = (RecyclerView) findViewById(R.id.myrecyclerview);
The layout also specifies which layout manager the RecyclerView uses to arrange its data.Note: You can dynamically set or change the
RecyclerViewlayout by callingRecyclerView.setLayoutManager()at run time. However, if you do not need to change the layout at runtime, we recommend that you set the layout manager in theRecyclerViewlayout file. Among other reasons, if you use the layout file, Android Studio can properly preview theRecyclerViewUI. -
The
onCreate()method creates an adapter; the adapter class is specified by the app, extending the Android Support Library'sRecyclerView.Adapterclass. Typically, when the app creates the adapter, the app passes the information the adapter needs to get its data.myAdapter = new CustomAdapter(myDataSet);
The adapter's constructor does any necessary initialization. For example, it might create an inflater to use for inflating the layouts of its view holders.Note: For performance reasons, you should separate the logic that updates your list's data from the logic that manages the layouts and assigns the data to them.
-
The
onCreate()method attaches the adapter to theRecyclerView.myRecyclerView.setAdapter(myAdapter);
The RecyclerView calls the adapter to create
any necessary view holders. Each view holder displays one item's data. For
example, a music app might use a view holder for each album.
-
The adapter class's definition specifies which class it uses as its view
holder:
public class CustomAdapter extends RecyclerView.Adapter<CustomViewHolder>
-
The Android Support Library calls the adapter's
onCreateViewHolder()method. That method needs to construct the view holder and set the view it uses to display its contents. Typically, it would set the view by inflating an XML layout file. Since the view holder is not yet assigned to any particular data, the method does not actually set the view's contents.// Inflate the view for this view holder View thisItemsView = myInflater.inflate(R.layout.list_item_layout, parent, false); // Call the view holder's constructor, and pass the view to it; // return that new view holder return new CustomViewHolder(thisItemsView); -
The Android Support Library then binds the view holder to its data. It
does this by calling the adapter's
onBindViewHolder()method, and passing the view holder's position in theRecyclerView. TheonBindViewHolder()method needs to fetch the appropriate data, and use it to fill in the view holder's layout. For example, if theRecyclerViewis displaying a list of names, the method might find the appropriate name in the list, and fill in the view holder'sTextViewwidget.@Override public void onBindViewHolder(CustomViewHolder holder, int position) { // Find out the data, based on this view holder's position String thisItemsName = myNameList.get(position); holder.nameTextView.setText(thisItemsName); } -
The Android Support Library repeats this process, creating and binding new
view holders until the visible portion of the
RecyclerViewis filled. It also creates and binds one or two more, so if the user scrolls the list, the new view holders are ready to display.
If the user scrolls the list, the Android Support Library brings the
already-prepared view holders into view, and creates and binds new ones as
necessary. It does not immediately destroy the view holders that have
scrolled out of sight; they are kept available, in case the user scrolls
back. However, after a certain number of view holders have been created,
the Android Support Library does not create new ones. Instead, it rebinds
existing view holders as needed by calling onBindViewHolder() for them, specifying a new position. That method updates
the view holder's contents, but it reuses the view that was already created
for that view holder. The method does not have to perform costly actions like
building or inflating a new view.
You may find the DiffUtil class
useful for determining which items in your list need to be updated.
If the list changes, the app calls an appropriate RecyclerView.Adapter notification method. The
Android Support Library responds to the notification by rebinding any
affected view holders, allowing their data to be updated. The app can
improve performance by choosing a more precise notification; for example,
if the data in a single item needs to be updated, the app can call notifyItemChanged(int), and the
Android Support Library will just rebind that one item if it is visible.
Customizing RecyclerView
You can customize the RecyclerView objects to
meet your specific needs. The standard classes provide all the functionality
that most developers will need; in many cases, the only customization you need
to do is design the view for each view holder and write the code to update
those views with the appropriate data. However, if your app has specific
requirements, you can modify the standard behavior in a number of ways. The
following sections describe some of the other common customizations.
Modifying the layout
The RecyclerView uses a layout manager app
to arrange the individual data items on the screen. The Android Support Library
includes three standard layout managers, each of which offers many
customization options:
LinearLayoutManagerarranges the items in a one-dimensional list. Using aRecyclerViewwithLinearLayoutManagerprovides functionality like the olderListViewlayout.GridLayoutManagerarranges the items in a two-dimensional grid, like the squares on a checkerboard. Using aRecyclerViewwithGridLayoutManagerprovides functionality like the olderGridViewlayout.StaggeredGridLayoutManagerarranges the items in a two-dimensional grid, with each column slightly offset from the one before, like the stars in an American flag.
If none of these layout managers suits your needs, you can create your own by
extending the RecyclerView.LayoutManager
abstract class.
Item animations
Whenever an item changes, the RecyclerView
uses an animator to change its appearance. This animator is an object that
extends the abstract RecyclerView.ItemAnimator class. By default, the
RecyclerView uses DefaultItemAnimator to
provide the animation. If you want to provide custom animations, you can define
your own animator object by extending RecyclerView.ItemAnimator.