Skip to content

Instantly share code, notes, and snippets.

@Plumillon
Last active April 1, 2022 07:29
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save Plumillon/f85c6be94e2fdaf339b9 to your computer and use it in GitHub Desktop.
Save Plumillon/f85c6be94e2fdaf339b9 to your computer and use it in GitHub Desktop.
Simpler generic RecyclerView.Adapter and RecyclerView.ViewHolder with click listener
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Plumillon Forge.
*/
public abstract class PFRecyclerViewAdapter<T> extends RecyclerView.Adapter<PFRecyclerViewAdapter.ViewHolder> {
private List<T> items;
private Context context;
private OnViewHolderClick<T> listener;
public interface OnViewHolderClick<T> {
void onClick(View view, int position, T item);
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private Map<Integer, View> views;
public ViewHolder(View view, OnViewHolderClick listener) {
super(view);
views = new HashMap<>();
views.put(0, view);
if (listener != null)
view.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (listener != null)
listener.onClick(view, getAdapterPosition(), getItem(getAdapterPosition()));
}
public void initViewList(int[] idList) {
for (int id : idList)
initViewById(id);
}
public void initViewById(int id) {
View view = (getView() != null ? getView().findViewById(id) : null);
if (view != null)
views.put(id, view);
}
public View getView() {
return getView(0);
}
public View getView(int id) {
if (views.containsKey(id))
return views.get(id);
else
initViewById(id);
return views.get(id);
}
}
protected abstract View createView(Context context, ViewGroup viewGroup, int viewType);
protected abstract void bindView(T item, PFRecyclerViewAdapter.ViewHolder viewHolder);
public PFRecyclerViewAdapter(Context context) {
this(context, null);
}
public PFRecyclerViewAdapter(Context context, OnViewHolderClick<T> listener) {
super();
this.context = context;
this.listener = listener;
items = new ArrayList<>();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
return new ViewHolder(createView(context, viewGroup, viewType), listener);
}
@Override
public void onBindViewHolder(PFRecyclerViewAdapter.ViewHolder holder, int position) {
bindView(getItem(position), holder);
}
@Override
public int getItemCount() {
return items.size();
}
public T getItem(int index) {
return ((items != null && index < items.size()) ? items.get(index) : null);
}
public Context getContext() {
return context;
}
public void setList(List<T> list) {
items = list;
}
public List<T> getList() {
return items;
}
public void setClickListener(OnViewHolderClick listener) {
this.listener = listener;
}
public void addAll(List<T> list) {
items.addAll(list);
notifyDataSetChanged();
}
public void reset() {
items.clear();
notifyDataSetChanged();
}
}
public class Tag {
public static final String DEFAULT_COLOR = "#B3E5FC";
public String name;
public String type;
public String primaryColor;
public Tag(String n, String t, String p) {
name = n;
type = t;
primaryColor = p;
}
}
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.scanners.android.bao.R;
import com.scanners.android.bao.api.model.Tag;
/**
* Created by Plumillon Forge.
*/
public class TagListAdapter extends PFRecyclerViewAdapter<Tag> {
public TagListAdapter(Context context, OnViewHolderClick listener) {
super(context, listener);
}
@Override
protected View createView(Context context, ViewGroup viewGroup, int viewType) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.item_text_color, viewGroup, false);
return view;
}
@Override
protected void bindView(Tag item, PFRecyclerViewAdapter.ViewHolder viewHolder) {
if (item != null) {
TextView name = (TextView) viewHolder.getView(R.id.text_name);
TextView type = (TextView) viewHolder.getView(R.id.text_type);
View verticalBar = viewHolder.getView(R.id.vertical_bar);
name.setText(item.name);
type.setText(item.type);
verticalBar.setBackgroundColor(item.primaryColor != null ? Color.parseColor(item.primaryColor) : Color.parseColor(Tag.DEFAULT_COLOR));
}
}
}
@dominicthomas
Copy link

I found this very useful as a simple straight forward generic adapter.

@andhikayuana
Copy link

this is very usefull, thanks alot.

@Drakot
Copy link

Drakot commented Jun 27, 2017

How to apply this with butterknife?

@source-creator
Copy link

source-creator commented Jul 5, 2017

@Drakot - To bind with ButterKnife, use: ButterKnife.bind(this, parentView); in the ViewHolder.

@charles-silva
Copy link

Hi, have a demo how to use it; thanks.

@jabita24a
Copy link

jabita24a commented Nov 23, 2017

Where can I get an example of how this code is used, there are some examples that I can use to simplify understanding.

I look forward to your comments and thank you in advance.

@Abdaaf
Copy link

Abdaaf commented Jan 12, 2018

For some reason the OnClickListener doesn't work. I have a renamed it to CustomAdapter and the UserAdapter is the one that I am trying to instantiate.
UserAdapter userAdapter = new UserAdapter(getContext(), new CustomAdapter.OnViewHolderClick() {
@OverRide
public void onClick(View view, int position, User item) {
// do stuff
}
});

@ashkanpower
Copy link

I have written a simple generic adapter that needs no code for adapters or holder.
Take a look please : https://github.com/ashkanpower/SURAdapter

@joaolisboa
Copy link

joaolisboa commented Feb 13, 2018

@timothycoutlakis that won't work since the bindings will be in TagListAdapter, so following the example it should be called in the createView before the view return with: ButterKnife.bind(this, view);

With some more changes one could push this to the generic Adapter but this would be the quickest way.

edit: I haven't tested but I think I'm actually mistaken. The view after recycling will display wrong results unless the binding occurs in a ViewHolder with a similar structure as a standard Adapter. I'm actually still trying to find a nice way to make use of this with ButterKnife but can't seem to.

@samigehi
Copy link

I modified @Plumillon code and created even more generic RecyclerView.Adapter
https://gist.github.com/Sumeet21/8b52dbf3222603ff8c28457905cc9c70

@sandipsavaliya112
Copy link

Hey mate, Nice one… Actually i has done some rework on that and see what we've got..
I've made it the most dynamic generic adapter ever.
https://medium.com/@sandipsavaliya/tired-with-adapters-4240e5f45c24

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment