4.4: RecyclerView
Contents:
- RecyclerView components
- Data
- RecyclerView
- Item Layout
- Layout Manager
- Animations
- Adapter
- ViewHolder
- Implementing a RecyclerView
- 1. Add the dependency to app/build.gradle
- 2. Add a RecyclerView to your activity's layout
- 3. Create the layout for one item
- 4. Create an adapter with a view holder
- 5. Implement the view holder class
- 6. Create the RecyclerVew
- Related practical
- Learn more
When you display a large number of items in a scrollable list, most items are not visible. For example, in a long list of words or many news headlines, the user only sees a small number of list items at a time.
Or you may have a dataset that changes as the user interacts with it. If you create a new view every time the data changes, that's also a lot of views, even for a small dataset.
From a performance perspective, you want to minimize the number of views kept around at any given point (Memory), and the number of views you have to create (Time). Both of these goals can be accomplished by creating somewhat more views than the user can see on the screen, and cache and reuse previously created views with different data as they scroll in and out of view.
The RecyclerView class is a more advanced and flexible version of ListView. It is a container for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views.
Use the RecyclerView widget when you need to display a large amount of scrollable data, or data collections whose elements change at runtime based on user action or network events.
RecyclerView components
To display your data in a RecyclerView, you need the following parts:
- Data. It doesn't matter where the data comes from. You can create the data locally, as you do in the practical, get it from a database on the device as you will do in a later practical, or pull it from the cloud.
A RecyclerView. The scrolling list that contains the list items.
An instance of RecyclerView as defined in your activity's layout file to act as the container for the views.
- Layout for one item of data. All list items look the same, so you can use the same layout for all of them. The item layout has to be created separately from the activity's layout, so that one item view at a time can be created and filled with data.
A layout manager. The layout manager handles the organization (layout) of user interface components in a view. All view groups have layout managers. For the LinearLayout, the Android system handles the layout for you. RecyclerView requires an explicit layout manager to manage the arrangement of list items contained within it. This layout could be vertical, horizontal, or a grid.
The layout manager is an instance of Recyclerview.LayoutManager to organize the layout of the items in the RecyclerView
An adapter. The adapter connects your data to the RecyclerView. It prepares the data and how will be displayed in a view holder. When the data changes, the adapter updates the contents of the respective list item view in the RecyclerView.
And an adapter is an extension of RecyclerView.Adapter. The adapter uses a ViewHolder to hold the views that constitute each item in the RecyclerView, and to bind the data to be displayed into the views that display it.
A view holder. The view holder extends the ViewHolder class. It contains the view information for displaying one item from the item's layout.
A view holder used by the adapter to supply data, which is an extension of RecyclerView.ViewHolder
The diagram below shows the relationship between these compoments.
Data
Any displayable data can be shown in a RecyclerView.
- Text
- Images
- Icons
Data can come from any source.
- Created by the app. For example, scrambled words for a game.
- From a local database. For example, a list of contacts.
- From cloud storage or the internet. For example news headlines.
RecyclerView
A RecyclerView is:
- A View group for a scrollable container
- Ideal for long lists of similar items
- Uses only a limited number of views that are re-used when they go off-screen. This saves memory and makes it faster to update list items as the user scrolls through data, because it is not necessary to create a new view for every item that appears.
- In general, the RecyclerView keeps as many item views as fit on the screen, plus a few extra at each end of the list to make sure that scrolling is fast and smooth.
Item Layout
The layout for a list item is kept in a separate file so that the adapter can create item views and edit their contents independently from the layout of the activity.
Layout Manager
A layout manager positions item views inside a view group, such as the RecyclerView and determines when to reuse item views that are no longer visible to the user. To reuse (or recycle) a view, a layout manager may ask the adapter to replace the contents of the view with a different element from the dataset. Recycling views in this manner improves performance by avoiding the creation of unnecessary views or performing expensive findViewById() lookups.
RecyclerView provides these built-in layout managers:
- LinearLayoutManager shows items in a vertical or horizontal scrolling list.
- GridLayoutManager shows items in a grid.
- StaggeredGridLayoutManager shows items in a staggered grid.
To create a custom layout manager, extend the RecyclerView.LayoutManager class.
Animations
Animations for adding and removing items are enabled by default in RecyclerView. To customize these animations, extend the RecyclerView.ItemAnimator class and use the RecyclerView.setItemAnimator() method.
Adapter
An Adapter helps two incompatible interfaces to work together. In the RecyclerView, the adapter connects data with views. It acts as an intermediary between the data and the view. The Adapter receives or retrieves the data, does any work required to make it displayable in a view, and places the data in a view.
For example, the adapter may receive data from a database as a Cursor object, extract the the word and its definition, convert them to strings, and place the strings in an item view that has two text views, one for the word and one for the definition. You will learn more about cursors in a later chapter.
The RecyclerView.Adapter implements a view holder, and must override the following callbacks:
onCreateViewHolder()
inflates an item view and returns a new view holder that contains it. This method is called when the RecyclerView needs a new view holder to represent and item.onBindViewHolder()
sets the contents of an item at a given position in the RecyclerView. This is called by the RecyclerView, for example, when a new item scrolls into view.getItemCount()
returns the total number of items in the data set held by the adapter.
View holder
A RecyclerView.ViewHolder describes an item view and metadata about its place within the RecyclerView. Each view holder holds one set of data. The adapter adds data to view holders for the layout manager to display.
You define your view holder layout in an XML resource file. It can contain (almost) any type of view, including clickable elements.
Implementing a Recycler View
Implementing a RecyclerView requires the following steps:
- Add the RecyclerView dependency to the app's app/build.gradle file.
- Add the RecyclerView to the activity's layout
- Create a layout XML file for one item
- Extend RecyclerView.Adapter and implement onCrateViewHolder and onBindViewHolder methods.
- Extend RecyclerView.ViewHolder to create a view holder for your item layout. You can add click behavior by overriding the onClick method.
- In your activity, In the onCreate method, create a RecyclerView and initialize it with the adapter and a layout manager.
1. Add the dependency to app/build.gradle
Add the recycler view library to your app/build.gradle file as a dependency. Look at the chapter on support libraries or the RecyclerView practical, if you need detailed instructions.
dependencies {
...
compile 'com.android.support:recyclerview-v7:24.1.1'
...
}
2. Add a RecyclerView to your activity's layout
Add the RecyclerView in your activity's layout file.
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
Use the recycler view from the support library to be compatible with older devices. The only required attributes are the id, along with the width and height. Customize the items, not this view group.
3. Create the layout for one item
Create an XML resource file and specify the layout of one item. This will be used by the adapter to create the view holder.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dp">
<TextView
android:id="@+id/word"
style="@style/word_title" />
</LinearLayout>
The text view has a @style
element. A style is a collection of properties that specifies the look of a view. You can use styles to share display attributes with multiple views. An easy way to create a style is to extract the style of a UI element that you already created. For example, after styling a TextView, Right-click > Refactor > Extract > Style on the element and follow the dialog prompts. More details on styles are in the practical and in a later chapter.
4. Create an adapter with a view holder
Extend RecyclerView.Adapter and implement the onCrateViewHolder and onBindViewHolder methods.
Create a new Java class with the following signature:
public class WordListAdapter extends RecyclerView.Adapter<WordListAdapter.WordViewHolder> {}
In the constructor, get an inflater from the current contex, and your data.
public WordListAdapter(Context context, LinkedList<String> wordList) {
mInflater = LayoutInflater.from(context);
this.mWordList = wordList;
}
For this adapter, you have to implement 3 methods.
- onCreateViewHolder() creates a view and returns it.
@Override public WordViewHolder onCreateViewHolder(ViewGroup parent, int viewType){ // Inflate an item view. View mItemView = mInflater.inflate(R.layout.wordlist_item, parent, false); return new WordViewHolder(mItemView, this); }
- onBindViewHolder() associates the data with the view holder for a given position in the RecyclerView.
@Override public void onBindViewHolder(WordViewHolder holder, int position) { // Retrieve the data for that position String mCurrent = mWordList.get(position); // Add the data to the view holder.wordItemView.setText(mCurrent); }
- getItemCount() returns to number of data items available for displaying.
@Override public int getItemCount() { return mWordList.size(); }
5. Implement the view holder class
Extend RecyclerView.ViewHolder to create a view holder for your item layout. You can add click behavior by overriding the onClick method.
This class is usually defined as an inner class to the adapter and extends RecyclerView.ViewHolder.
class WordViewHolder extends RecyclerView.ViewHolder {}
If you want to add click handling, you need to implement a click listener. One way to do this is to have the view holder implement the click listener methods.
// Extend the signature of WordVewHolder to implement a click listener.
class WordViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {}
In its constructor, the view holder has to inflate its layout, associate with its adapter, and, if applicable, set a click listener.
public WordViewHolder(View itemView, WordListAdapter adapter) {
super(itemView);
wordItemView = (TextView) itemView.findViewById(R.id.word);
this.mAdapter = adapter;
itemView.setOnClickListener(this);
}
And, if you implementing onClickListener, you also have to implement onClick().
@Override
public void onClick(View v) {
wordItemView.setText ("Clicked! "+ wordItemView.getText());
}
Note that to attach click listeners to other elements of the view holder, you do that dynamically in onBindViewHolder. (You will do this a later practical, when you will be extending the recycler view code from the practical.)
6. Create the RecyclerView
Finally, to tie it all together, in your activity's onCreate() method:
- Get a handle to the RecyclerView.
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
- Create an adapter and supply the data to be displayed.
mAdapter = new WordListAdapter(this, mWordList);
- Connect the adapter with the recycler view.
mRecyclerView.setAdapter(mAdapter);
- Give the recycler view a default layout manager.
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
RecyclerView is an efficient way for displaying scrolling list data. It uses the adapter pattern to connect data with list item views. To implement a RecyclerView you need to create an adapter and a view holder, and the methods that take the data and add it to the list items.
Related practical
The related exercises and practical documentation is in Android Developer Fundamentals: Practicals.
Learn more
- RecyclerView
- RecyclerView class
- RecyclerView.Adapter class
- RecyclerView.ViewHolder class
- RecyclerView.LayoutManager class