RecyclerView Adapters part 1: RecyclerView Array Adapter

Nowadays most Android developers use the new RecyclerView instead of a ListView or GridView. The RecyclerView widget is a more advanced and flexible version of ListView. This widget is a container for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views.

The sad thing is that Google didn’t provide us with a set af default RecyclerView Adapter classes to extend from, like they previously did for the ListView. The first one I’ll discuss is a RecyclerView Array Adapter, which allows you to easily bind a List of objects to your RecyclerView.

import android.support.v7.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public abstract class RecyclerViewArrayAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH>
{
    private final List<T> items;

    public void bindData(final List<T> items)
    {
        this.items = items;
        this.notifyDataSetChanged();
    }

    public final T getItem(final int position)
    {
        return this.items.get(position);
    }

    public List&lt;T&gt; getItems()
    {
        return items;
    }

    @Override
    public int getItemCount()
    {
        return this.items != null
                ? this.items.size()
                : 0;
    }

    @Override
    public final void onBindViewHolder(final VH holder, final int position)
    {
        final T item = this.getItem(position);
        this.onBindViewHolder(holder, item);
    }

    public abstract void onBindViewHolder(final VH holder, final T item);
}

This class isn’t hard to come up with and doesn’t contain a lot of logic, but it should prevent you to re-implement this logic every time you need an Adapter class containing a simple list of items.

Below you can find a simple Adapter for showing search resutls into a RecyclerView.

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import butterknife.Bind;
import butterknife.ButterKnife;

public class SearchResultsAdapter extends RecyclerViewArrayAdapter<SearchResult, SearchResultsAdapter.SearchResultViewHolder>
    implements View.OnClickListener
{
    private final LayoutInflater layoutInflater;
    private OnItemClickListener onItemClickListener;

    public SearchResultsAdapter(final Context context)
    {
        super();

        this.layoutInflater = LayoutInflater.from(context);
    }

    public void setOnItemClickListener(final OnItemClickListener onItemClickListener)
    {
        this.onItemClickListener = onItemClickListener;
    }

    @Override
    public SearchResultViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType)
    {
        final View view = this.layoutInflater.inflate(R.layout.listitem_search, parent, false);
        view.setOnClickListener(this);

        return new SearchResultViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final SearchResultViewHolder holder, final SearchResult item)
    {
        holder.bindData(item);
    }

     /*
     * View.OnClickListener
     */

    @Override
    public void onClick(final View view)
    {
        if (this.onItemClickListener != null)
        {
            final RecyclerView recyclerView = (RecyclerView) view.getParent();
            final int position = recyclerView.getChildLayoutPosition(view);
            if (position != RecyclerView.NO_POSITION)
            {
                final SearchResult item = this.getItem(position);
                this.onItemClickListener.onItemClicked(item);
            }
        }
    }

    public static class SearchResultViewHolder extends RecyclerView.ViewHolder
    {
        @Bind(R.id.textview_name)
        TextView textViewName;

        public SearchResultViewHolder(final View itemView)
        {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        public void bindData(final SearchResult item)
        {
            this.textViewName.setText(item.getName());
        }
    }

    public interface OnItemClickListener
    {
        void onItemClicked(SearchResult item);
    }
}

Passing the items to the adapter:

final List<SearchResult> items = this.getSearchResults();
this.adapter.bindData(items);
device-2015-09-25-135150