Skip to content

Commit

Permalink
Boilerplate code to handle Android's RecyclerView Adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
SeanZoR committed Mar 2, 2015
1 parent e2ca415 commit 3c364b7
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.tipz.helpers.view.adapter;

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

import java.util.ArrayList;

/**
* This boilerplate code helps manage the RecyclerView adapter code
* It is designed to work when you:
* <ul>
* <li>Using ArrayList to manage your data</li>
* <li>Have a single type of data in the adapter</li>
* </ul>
*
* @param <VIEW_HOLDER> - The ViewHolder Type that references the views in a single item
* @param <DATA> - The Data Type that will be saved in the ArrayList
*/
public abstract class BaseRecyclerArrayAdapter<VIEW_HOLDER extends BaseRecyclerViewHolder, DATA>
extends RecyclerView.Adapter<VIEW_HOLDER> {

protected final ArrayList<DATA> mData;

/**
* Construct an adapter with data in it
*
* @param data the data for the adapter to display
*/
public BaseRecyclerArrayAdapter(ArrayList<DATA> data) {
// Note this will be used internally by the adapter.
// This is passed by reference, and by that is subject to changes from
// outside the adapter.
mData = data;
}

@Override
public VIEW_HOLDER onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(getSingleItemLayoutRes(), null);
return (VIEW_HOLDER) BaseRecyclerViewHolder.create(getViewHolderClass(), v);
}

@Override
public void onBindViewHolder(VIEW_HOLDER viewHolder, int position) {
onBindViewHolderToData(viewHolder, mData.get(position));
}

@Override
public int getItemCount() {
return mData.size();
}

protected abstract Class getViewHolderClass();

protected abstract int getSingleItemLayoutRes();

protected abstract void onBindViewHolderToData(VIEW_HOLDER viewHolder, DATA data);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.tipz.helpers.view.adapter;

import android.support.v7.widget.RecyclerView;
import android.view.View;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

/**
* Represents an abstract view holder with auto-binding functions
* NOTE: If subclassed from an Internal class, it must be a static class
*/
public abstract class BaseRecyclerViewHolder extends RecyclerView.ViewHolder {

public BaseRecyclerViewHolder(View itemView) {
super(itemView);
}

public static <T> T create(Class<T> cls, View view) {
T entity = null;
try {
final Constructor<T> constructor = cls.getConstructor(View.class);
entity = constructor.newInstance(view);

// Run on all the fields in the API object
for (Field currField : entity.getClass().getFields()) {

// If this field has annotation
if (currField.getAnnotation(ViewHolderBinder.class) != null) {
// Check to see the db name of the fields
ViewHolderBinder annotation = currField.getAnnotation(ViewHolderBinder.class);
int resId = annotation.resId();

currField.set(entity, view.findViewById(resId));
}
}
} catch (Exception e) {
e.printStackTrace();
}

return entity;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.tipz.helpers.view.adapter;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ViewHolderBinder {

int resId() default 0;
}

2 comments on commit 3c364b7

@SeanZoR
Copy link
Owner Author

@SeanZoR SeanZoR commented on 3c364b7 Mar 2, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sample on how to use:

public class TipsAdapter extends BaseRecyclerArrayAdapter<TipsAdapter.TipViewHolder, TipEntity> {

    /**
     * Construct an adapter with data in it
     *
     * @param data the data for the adapter to display
     */
    public TipsAdapter(ArrayList<TipEntity> data) {
        super(data);
    }

    @Override
    protected Class getViewHolderClass() {
        return TipViewHolder.class;
    }

    @Override
    protected int getSingleItemLayoutRes() {
        return R.layout.item_tips;
    }

    @Override
    public void onBindViewHolderToData(TipViewHolder holder, TipEntity data) {
        // Bind the data to the view holder
        holder.title.setText(data.title);
    }


    public static class TipViewHolder extends BaseRecyclerViewHolder {

        public TipViewHolder(View itemView) {
            super(itemView);
        }

        @ViewHolderBinder(resId = R.id.item_tips_title)
        public TextView title;

    }
}

(see: e7a51a2)

@ZkHaider
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if you have multiple view types

Please sign in to comment.