Skip to content

Instantly share code, notes, and snippets.

@mahdi-malv
Created July 21, 2018 14:47
Show Gist options
  • Save mahdi-malv/1fee0f9ef303c982e959f75f6c6ba5b6 to your computer and use it in GitHub Desktop.
Save mahdi-malv/1fee0f9ef303c982e959f75f6c6ba5b6 to your computer and use it in GitHub Desktop.
RecyclerAdapter to simplify adapting recyclerView
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class ListClick implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public ListClick(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildAdapterPosition(child)); // in case of deprication: use getChildAdapterPosition
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildAdapterPosition(child)); // in case of deprication: use getChildAdapterPosition
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface ClickListener {
void onClick(View view, int position);
/**
* to Add support for extension methods you must use Java 8 or above
* to do that Add this block to `build.gradle(Module: your module like app)` inside android block
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
* This feature makes onLongClick optional
*/
default void onLongClick(View view, int position) {}
}
}
import android.content.Context;
import android.content.res.Resources;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
public class ListConfig<T> {
private Context c;
private List<T> set;
private RecyclerView list;
private int resLayout = 0;
private RecyclerView.LayoutManager layoutManager;
private ListClick.ClickListener onClick;
private BindHolder<T> bindHolder;
private CreateViewHolder createViewHolder = null;
public ListConfig(Context c) {
this.c = c;
}
public ListConfig<T> with(List<T> set) {
if (set == null) throw new NullPointerException("List of data can not be null");
else this.set = set;
return this;
}
public ListConfig<T> resLayout(int layout) {
this.resLayout = layout;
return this;
}
public ListConfig<T> layoutManager(RecyclerView.LayoutManager layoutManager) {
if (layoutManager == null) throw new NullPointerException("If you want to use default, Don't invoke this function.");
this.layoutManager = layoutManager;
return this;
}
public ListConfig<T> onBindViewHolder(BindHolder<T> onBind) {
bindHolder = onBind;
return this;
}
public ListConfig<T> onClick(ListClick.ClickListener listener) {
onClick = listener;
return this;
}
/**
* OnCreateView holder can be customized here. This is optional
*/
public ListConfig<T> setOnCreateViewHolder(CreateViewHolder onCreateViewHolder) {
this.createViewHolder = onCreateViewHolder;
return this;
}
public void into(RecyclerView list) {
this.list = list;
list.setLayoutManager(layoutManager == null ? new LinearLayoutManager(c) : layoutManager);
list.setHasFixedSize(true);
list.setAdapter(new Adapter(set, resLayout, bindHolder, createViewHolder));
list.addOnItemTouchListener(new ListClick(c, list, onClick));
}
public static class VH extends RecyclerView.ViewHolder {
VH(View itemView) {
super(itemView);
}
}
public class Adapter extends RecyclerView.Adapter<VH> {
private List<T> set;
private int resLayout;
private BindHolder<T> bindHolder;
private CreateViewHolder createViewHolder = null;
public Adapter(List<T> set, int resLayout, BindHolder<T> bindHolder, CreateViewHolder createViewHolder) {
this.set = set;
this.resLayout = resLayout;
this.bindHolder = bindHolder;
this.createViewHolder = createViewHolder;
}
@Override
public VH onCreateViewHolder(ViewGroup parent, int viewType) {
if (createViewHolder == null) {
if (resLayout == 0) throw new Resources.NotFoundException("You have not passed the resource or correct resource.");
View v = LayoutInflater.from(parent.getContext()).inflate(resLayout, parent, false);
return new VH(v);
} else {
return createViewHolder.onCreateViewHolder(parent, viewType);
}
}
@Override
public void onBindViewHolder(VH holder, int position) {
bindHolder.onBind(holder, set.get(position), position);
}
@Override
public int getItemCount() {
return set.size();
}
}
//Interfaces
public interface BindHolder<T> {
void onBind(VH holder, T item, int position);
}
public interface CreateViewHolder {
VH onCreateViewHolder(ViewGroup parent, int viewType);
}
}
new ListConfig<Datum>(context) //pass Context and Generic can be anything
.with(set) // List of <Datum>
.resLayout(R.layout.layout) // Resource layout
.layoutManager(new GridLayouManager(context, 2)) // Optional: default is LinearLayoutManager
.onBindViewHolder((holder, item, position) -> { // what happens in onBindViewHolder and also in ViewHolder
// Also item is `set.get(position)`
TextView title = holder.itemView.findViewById(R.id.name); // Create and instantiate your views here using itemView of holder
title.setText(item.getName());
title.setTextColor(color);
TextView model = holder.itemView.findViewById(R.id.model);
model.setText(item.getModel());
/* Assume you have a Datum class that has name and model (For example) */
})
.onClick((view, position) -> { // onClick - Optional: OnLongClick is also available
Toast.makeText(getActivity(), "Item clicked!", Toast.LENGTH_SHORT).show();
})
.into(list); // must be invoked at the end of chain (returns void) - Others can be moved in order
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment