Writing a basic RecyclerView.Adapter
and how it is similar to a typical getView() implementation
In my previous article, ListView and ViewHolder, I discussed about the ViewHolder pattern and how it should be combined to be a part of an adapter for a ListView, or more specifically - a part of an adapter's getView() method.
We had a simple model named Profile, which describes some basic information of a person. It has an image, a name and a short bio:
public class Profile {
    /**
     * Name of person.
     */
    private String mName;
    /**
     * Bio.
     */
    private String mBio;
    /**
     * Profile image resource.
     */
    private int mProfileImageResource;
    public Profile(String name, String bio, int profileImageResource) {
        mName = name;
        mBio = bio;
        mProfileImageResource = profileImageResource;
    }
    /* "Get" methods... */
}
Our adapter, MyArrayAdapter, mapped Profile's three members ( name, bio and image ) to matching Views in our layout  (R.layout.list_item): two TextViews for name and bio and an ImageView for the image. Let's remember that instead of using findViewById() multiple times ( to find these three Views as getView() is being called ), we created a ViewHolder and used it to map a Profile to a visual layout.
This mapping process is called binding. We can say that we bind ViewHolder's members ( Our layout's Views ) to a Profile.
If we first create a ViewHolder and  then bind a ViewHolder, wouldn't it make sense to split these two tasks into two methods onCreateViewHolder() and onBindViewHolder() ?
This is exactly what RecyclerView.Adapter does!
RecyclerView.Adapter declares two abstract methods which we obviously must implement when we extend it:
public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);
public abstract void onBindViewHolder(VH holder, int position);
RecyclerView.Adapter is responsible for invoking these two methods whenever there's a need to create or bind a ViewHolder.
You can see that onCreateViewHolder() returns a VH type, and I can tell you that onBindViewHolder() receives this exact returned value as an argument. VH stands for View Holder and it's a generic type which needs to extend RecyclerView.ViewHolder and which we need to implement. Let's call it MyViewHolder :
    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView name;
        TextView bio;
        ImageView img;
        MyViewHolder(View itemView) {
            super(itemView);
            name = (TextView) itemView.findViewById(R.id.tv_name);
            bio = (TextView) itemView.findViewById(R.id.tv_bio);
            img = (ImageView) itemView.findViewById(R.id.iv_profile_image);
        }
    }
In its constructor, MyViewHolder receives the itemView argument, which is the inflated layout (R.layout.list_item) in which and by which we find all other child views: name, bio and img.
MyViewHolder's constructor executes a series of calls to findViewById(), one for each View in our layout and keeps references to each one of the Views.
To get a better idea on how to implement onCreateViewHolder() and onBindViewHolder() having MyViewHolder implementation, let's look at their similarity with our already implemented getView() in the previous article - ListView and ViewHolder

OK, things are getting more clear now.onBindViewHolder()'s implementation is just a copy-paste task:
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        final Profile profile = mProfiles.get(position);
        holder.name.setText(profile.getName());
        holder.bio.setText(profile.getBio());
        holder.img.setImageResource(profile.getProfileImageResource());
    }
Finally, we can write onCreateViewHolder() to create a MyViewHolder and return it, so that onBindViewHolder() will receive it as an argument later and continue with the binding process:
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        final View itemView = View.inflate(mContext, R.layout.list_item, null);
        return new MyViewHolder(itemView);
    }
Connecting all the pieces, we can now write our adapter - MyProfilesAdapter :
class MyProfilesAdapter extends RecyclerView.Adapter<MyProfilesAdapter.MyViewHolder> {
    private Context mContext;
    private List<Profile> mProfiles = Collections.emptyList();
    MyProfilesAdapter(Context context, List<Profile> profiles) {
        mContext = context;
        mProfiles = profiles;
    }
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        final View itemView = View.inflate(mContext, R.layout.list_item, null);
        return new MyViewHolder(itemView);
    }
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        final Profile profile = mProfiles.get(position);
        holder.name.setText(profile.getName());
        holder.bio.setText(profile.getBio());
        holder.img.setImageResource(profile.getProfileImageResource());
    }
    @Override
    public int getItemCount() {
        return mProfiles.size();
    }
    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView name;
        TextView bio;
        ImageView img;
        MyViewHolder(View itemView) {
            super(itemView);
            name = (TextView) itemView.findViewById(R.id.tv_name);
            bio = (TextView) itemView.findViewById(R.id.tv_bio);
            img = (ImageView) itemView.findViewById(R.id.iv_profile_image);
        }
    }
}
