Categories: Android / Developers / Mobile Apps


If you’ve worked in Android before, chances are you have used a ListView, or possibly a GridView. These views make it pretty straightforward to build a scrollable list of data that users can view and interact with, the foundation of a majority of the apps you likely use on a day to day basis. While these views did their job, and did it well, they could be a little rough around the edges when you wanted to implement some of the more recent design and development patterns. As of API level 23 (with a support library version included as well) Google has added a new view, known as the RecyclerView, and it’s pretty great.

The RecyclerView gives you more control over how your list items are laid out in the view in the form of LayoutManagers. These layout managers let you inform the RecyclerView how you would like each individual item to be positioned. There are currently three LayoutManagers provided in Android:

  • LinearLayoutManager
    This LayoutManager gives you a layout similar to a standard ListView. As it’s name suggests, it lays out the child list items linearly, in either a horizontal or vertical orientation.
  • GridLayoutManager
    This LayoutManager, as you may have guessed, lets you lay out your items in a grid. By passing in your own SpanSizeLookup subclass you can control the span size of each item, allowing you to create some of the more complicated grid layouts.
  • StaggeredGridLayoutManager
    This LayoutManager is a more specific version of the GridLayoutManager. It will have the RecyclerView lay out the child elements in a staggered grid based on their width and height. For example, if the first item were to be 100×200 (WxH) and the next two items were to be 100×100, you would see the first item laid out in the left column, and the second and third would be laid out in the right column (depending on your span widths).

There is a lot you can do with the LayoutManagers, but that is the topic of another blog post. For the remainder of this post we’ll look at how we can use a RecyclerView.

The first thing we need to do is create a ViewHolder. Before the RecyclerView, it was very common for developers to create their own ViewHolder and associate it with a list item view by setting it as the views tag. With the RecyclerView we create an object that extends RecyclerView.Adapter and pass that to the Adapter, which will now handle the process of creating new ViewHolders and associating them with views. Below is an example of a basic ViewHolder:

private class RecyclerViewHolder extends RecyclerView.ViewHolder {

    private TextView mTitleView;
    private TextView mDetailView;

    public RecyclerViewHolder(View itemView) {
        super(itemView);
        mTitleView = (TextView) itemView.findViewById(R.id.title);
        mDetailView = (TextView) itemView.findViewById(R.id.detail);
    }

    public TextView getTitleView() {
        return mTitleView;
    }

    public TextView getDetailView() {
        return mDetailView;
    }
}

In the ViewHolder we simply need to declare member variables for whatever subviews we want to be able to access, and then assign them in the constructor, which will be passed the inflated view it will be associated, in this case called itemView. I’ve defined the member variables as private and declared accessors here to make things a bit cleaner but it’s up to your preference for how you access your views.

Next we need to define an adapter. The adapter will handle inflating the views, creating the view holders, and binding the views. We do this by extending RecyclerView.Adapter<RecyclerViewHolder> and overriding three methods:

  • getItemCount
    Here we simply return the total number of items in our data set.
  • onCreateViewHolder
    In this method we receive the parent view for the list item view and a viewType identifier. The viewType value is useful if we want to have multiple types of list item views in the same list.
  • onBindViewHolder
    In this method we receive the ViewHolder we created in onCreateViewHolder and an integer position. Here we can get the item represented by the position and populate the views we stored in the ViewHolder.

As an example we’ll create a basic DataObject to hold our title and details:

private class DataObject extends Object {

    public String title;
    public String details;
}

Then we can create our adapter:

private class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {

    private List<DataObject> mDataObjects;

    public RecyclerViewAdapter(List<DataObject> objects) {
        super();
        mDataObjects = objects;
    }

    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        // Retrieve the layout inflater
        LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(LAYOUT_INFLATER_SERVICE);

        // Inflate the list item
        View view = inflater.inflate(R.layout.list_item_object, parent, false);

        // Create and return the view holder

        return new RecyclerViewHolder(view);

    }

    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, int position) {

        // Retrieve the object for the current position
        DataObject object = mDataObjects.get(position);

        // Populate the views
        holder.getTitleView().setText(object.title); holder.getDetailView().setText(object.details);
    }

    @Override
    public int getItemCount() {

        return mDataObjects.size();

    }
}

Now all we need to do in our Activity or Fragment is pass a LayoutManager to the RecyclerView:

mRecylerView.setLayoutManager(new LinearLayoutManager(this)); 

//Create our adapter and pass it our list data:
mAdapter = new RecyclerViewAdapter(mDataObjects);

//And pass our adapter to the RecyclerView:
mRecyclerView.setAdapter(adapter);

As I mentioned before this is just the beginning of what you can do with a RecyclerView. You can get incredible control over your list layout and enable yourself to build some truly amazing apps. Be aware, however, that it leaves some things up to you that would normally be handled by a ListView, such as onClick listeners. With RecyclerView you are now responsible for setting up your own gesture recognizers and communicating with the controller. While this isn’t too difficult to do, keep this in mind when deciding whether to use a ListView or RecyclerView. If you just need a basic list, you may still be happier going with a ListView and saving the RecyclerView for some of your more complex layouts.



Touchtap is a digital agency specializing in mobile-first development.We can build your mobile app for you.

Back to Posts