Skip to content

Instantly share code, notes, and snippets.

@chRyNaN
Created March 31, 2016 00:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save chRyNaN/129a03af58c9f61f99095dad1a1c26e2 to your computer and use it in GitHub Desktop.
Save chRyNaN/129a03af58c9f61f99095dad1a1c26e2 to your computer and use it in GitHub Desktop.
Classes to bridge the gap between RecyclerView and ListView by providing a common API.
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Created by chRyNaN on 3/30/2016. This class combines the logic of an ArrayAdapter and a RecyclerView.Adapter.
* Handles boilerplate code to conveniently provide accessing and editing of Objects.
*/
public abstract class ItemAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
private List<T> items;
private Context context;
/**
* Default constructor.
* @param context Associates this adapter with the specified context.
*/
public ItemAdapter(Context context){
super();
this.context = context;
this.items = new ArrayList<>();
}
/**
* Overloaded constructor for conveniently adding a list of items on creation.
* @param context Associates this adapter with the specified context.
* @param items Adds this list of items into the underlying list data structure.
*/
public ItemAdapter(Context context, List<T> items){
super();
this.context = context;
this.items = items;
}
@Override
public void onBindViewHolder(VH holder, int position) {
onBindViewHolder(holder, getItem(position), position);
}
/**
* Overloaded version of the onBindViewHolder method providing easier access to the item at this position.
* @param holder The ViewHolder which should be updated to represent the contents of the item at the given
* position in the data set.
* @param item The item at the specified position within the adapter's data set.
* @param position The position of the item within the adapter's data set.
*/
public abstract void onBindViewHolder(VH holder, T item, int position);
@Override
public int getItemCount() {
if(items != null){
return items.size();
}
return 0;
}
@Override
public long getItemId(int position){
return getItem(position).hashCode();
}
/**
* Retrieves the context associated with this adapter.
* @return Context The context provided in the constructor.
*/
public Context getContext(){
return context;
}
/**
* Retrieves the item at the specified position.
* @param position The index in the adapter's data set where the item is located.
* @return T The item at the specified position or null if the data set is null.
*/
public T getItem(int position){
if(items != null){
return items.get(position);
}
return null;
}
/**
* Retrieves the index of the specified item.
* @param item The object whose position we are retrieving from the underlying data set.
* @return int The index of the item or -1 if the data set is null or the item is not in the data set.
*/
public int getPosition(T item){
if(items != null){
return items.indexOf(item);
}
return -1;
}
/**
* Adds the item to the data set.
* @param item The item to be added.
*/
public void add(T item){
if(items == null){
items = new ArrayList<>();
}
items.add(item);
notifyItemInserted(getItemCount() - 1);
}
/**
* Adds all of the items to the data set.
* @param items The item list to be added.
*/
public void addAll(List<T> items){
if(this.items == null){
this.items = new ArrayList<>();
}
this.items.addAll(items);
notifyDataSetChanged();
}
/**
* Adds all of the items to the data set.
* @param items The item collection to be added.
*/
public void addAll(Collection<T> items){
if(this.items == null){
this.items = new ArrayList<>();
}
this.items.addAll(items);
notifyDataSetChanged();
}
/**
* Adds all of the items to the data set.
* @param items The item array to be added.
*/
public void addAll(T[] items){
if(this.items == null){
this.items = new ArrayList<>();
}
for(int i = 0; i < items.length; i++){
this.items.add(items[i]);
}
notifyDataSetChanged();
}
/**
* Removes the specified item from the underlying data set.
* @param item The item to be removed.
* @return boolean The boolean representing if the item was in the data set. True if the item was removed, false
* if the item wasn't in the data set or the data set was null.
*/
public boolean remove(T item){
boolean b = false;
if(items != null){
int i = items.indexOf(item);
b = items.remove(item);
if(b && i != -1){
notifyItemRemoved(i);
}
}
return b;
}
/**
* Inserts the specified item at the specified location in the underlying data set.
* @param item The item to be inserted.
* @param position The index where the item is to be inserted.
*/
public void insert(T item, int position){
if(items == null){
items = new ArrayList<>();
}
this.items.add(position, item);
notifyItemInserted(position);
}
/**
* Clears all items from the data set.
*/
public void clear(){
if(items != null){
items.clear();
notifyDataSetChanged();
}
}
/**
* Sorts all the items in the data set.
* @param comparator The comparator used to sort the items.
*/
public void sort(Comparator<? super T> comparator){
if(items != null){
Collections.sort(items, comparator);
notifyDataSetChanged();
}
}
}
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
/**
* Created by chRyNaN on 3/30/2016. This class is very similar to an ItemAdapter
* (https://gist.github.com/chRyNaN/fd433c680b85b2ef267448b75ecac0ae) but instead of being used on a
* RecyclerView this adapter is used on a ListView or any View that uses an ArrayAdapter. This class
* mimics some, but not all, behavior that is present in a RecyclerView.Adapter (ex: it provides
* abstractions for View recycling and calls methods, such as, onCreateViewHolder and onBindViewHolder).
* Provides a similar API for RecyclerView.Adapter and ArrayAdapter to ease the transition between the two.
*/
public abstract class ListItemAdapter<T, VH extends ViewHolder> extends ArrayAdapter<T> {
/**
* Default constructor specifying the context used to create this adapter.
* @param context The context used to create this adapter.
*/
public ListItemAdapter(Context context){
super(context, 0);
}
/**
* Retrieves the ViewHolder object containing a View used to display an item.
* @param parent The parent View containing all Views to be displayed from this adapter.
* @param viewType The type of View used to create the correct ViewHolder instance.
* @return
*/
public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);
/**
* Binds the data item to the View to be displayed.
* @param holder The ViewHolder created in onCreateViewHolder for this item instance.
* @param item The item object at this position.
* @param position The position in the data set for this item.
*/
public abstract void onBindViewHolder(VH holder, T item, int position);
/**
* Similar to the onCreateViewHolder() method except it is specific for the dropdown View.
* @param parent The parent View containing all Views to be displayed from this adapter.
* @param viewType The type of View used to create the correct ViewHolder instance.
* @return
*/
public VH onCreateDropDownViewHolder(ViewGroup parent, int viewType){return null;}
/**
* Similar to the onBindViewHolder() method except it is specific for the dropdown View.
* @param holder The ViewHolder created in onCreateViewHolder for this item instance.
* @param item The item object at this position.
* @param position The position in the data set for this item.
*/
public void onBindDropDownViewHolder(VH holder, T item, int position){}
@Override
public View getView(int position, View convertView, ViewGroup parent){
VH holder;
if(convertView == null){
holder = onCreateViewHolder(parent, getItemViewType(position));
if(holder != null) {
convertView = holder.getBaseView();
convertView.setTag(holder);
}
}else{
holder = (VH) convertView.getTag();
if(holder == null){
holder = onCreateViewHolder(parent, getItemViewType(position));
if(holder != null) {
convertView = holder.getBaseView();
convertView.setTag(holder);
}
}
}
onBindViewHolder(holder, getItem(position), position);
return convertView;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent){
VH holder;
if(convertView == null){
holder = onCreateDropDownViewHolder(parent, getItemViewType(position));
if(holder != null) {
convertView = holder.getBaseView();
convertView.setTag(holder);
}
}else{
holder = (VH) convertView.getTag();
if(holder == null){
holder = onCreateDropDownViewHolder(parent, getItemViewType(position));
if(holder != null) {
convertView = holder.getBaseView();
convertView.setTag(holder);
}
}
}
onBindDropDownViewHolder(holder, getItem(position), position);
return convertView;
}
/**
* Delegation method for getCount() to follow the RecyclerView.Adapter method naming conventions.
* @return int Amount of items in the underlying data set.
*/
public int getItemCount(){
return getCount();
}
}
import android.view.View;
/**
* Created by chRyNaN on 3/30/2016. A class that can be used similar to how a RecyclerView.ViewHolder class is used with
* the exception that it doesn't contain any information about its position in the adapter.
*/
public class ViewHolder {
private View baseView;
private int itemViewType;
/**
* Default constructor providing the base View of this ViewHolder.
* @param v The base View of the ViewHolder.
*/
public ViewHolder(View v){
if(v == null){
throw new IllegalArgumentException("View parameter in ViewHolder constructor must not be null.");
}
this.baseView = v;
this.itemViewType = -1;
}
/**
* Constructor providing the base View of the ViewHolder and the int representing the item view type.
* @param v The base View of the ViewHolder.
* @param itemViewType The item view type; user defined, should correspond to the item view type from the
* onCreateViewHolder() method.
*/
public ViewHolder(View v, int itemViewType){
this(v);
this.itemViewType = itemViewType;
}
/**
* Retrieves the base View defined when creating this ViewHolder.
* @return View The base View of this ViewHolder.
*/
public View getBaseView(){
return baseView;
}
/**
* Retrieves the item view type.
* @return int The item view type or -1 if none was specified.
*/
public int getItemViewType(){
return itemViewType;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment