Project on github: passsy/ArrayAdapter
dependencies {
compile 'com.pascalwelsch.arrayadapter:arrayadapter:1.2.0'
}
Project on github: passsy/ArrayAdapter
dependencies {
compile 'com.pascalwelsch.arrayadapter:arrayadapter:1.2.0'
}
| package com.pascalwelsch.utils; | |
| import android.support.annotation.Nullable; | |
| import android.support.v7.util.DiffUtil; | |
| import android.support.v7.widget.RecyclerView; | |
| import java.util.ArrayList; | |
| import java.util.Collections; | |
| import java.util.Comparator; | |
| import java.util.List; | |
| /** | |
| * Simple adapter implementation analog to {@link android.widget.ArrayAdapter} for {@link | |
| * android.support.v7.widget.RecyclerView}. Holds to a list of objects of type {@link T} | |
| * | |
| * Created by Pascal Welsch on 04.07.14. | |
| * | |
| * source: https://gist.github.com/passsy/f8eecc97c37e3de46176 | |
| */ | |
| public abstract class ArrayAdapter<T, VH extends RecyclerView.ViewHolder> | |
| extends RecyclerView.Adapter<VH> { | |
| public interface StableIdProvider<T> { | |
| Object getId(T item); | |
| } | |
| private List<T> mObjects; | |
| public ArrayAdapter(@Nullable final List<T> objects) { | |
| mObjects = objects != null ? objects : new ArrayList<T>(); | |
| } | |
| public ArrayAdapter() { | |
| this(null); | |
| } | |
| /** | |
| * Adds the specified object at the end of the array. | |
| * | |
| * @param object The object to add at the end of the array. | |
| */ | |
| public void add(final T object) { | |
| mObjects.add(object); | |
| notifyItemInserted(getItemCount() - 1); | |
| } | |
| /** | |
| * Adds the specified list of objects at the end of the array. | |
| * | |
| * @param objects The objects to add at the end of the array. | |
| */ | |
| public void addAll(final List<T> objects) { | |
| if (objects == null) { | |
| mObjects.clear(); | |
| } else { | |
| mObjects.addAll(objects); | |
| } | |
| notifyDataSetChanged(); | |
| } | |
| /** | |
| * Inserts the specified object at the specified index in the array. | |
| * | |
| * @param object The object to insert into the array. | |
| * @param position The index at which the object must be inserted. | |
| */ | |
| public void addItem(final int position, final T object) { | |
| mObjects.add(position, object); | |
| notifyItemInserted(position); | |
| } | |
| /** | |
| * Adds the specified object to the end of the array. | |
| * | |
| * @param object The object to append | |
| */ | |
| public void addItem(final T object) { | |
| addItem(mObjects.size(), object); | |
| } | |
| /** | |
| * Remove all elements from the list. | |
| */ | |
| public void clear() { | |
| final int size = getItemCount(); | |
| mObjects.clear(); | |
| notifyItemRangeRemoved(0, size); | |
| } | |
| public T getItem(final int position) { | |
| try { | |
| return mObjects.get(position); | |
| } catch (IndexOutOfBoundsException e) { | |
| return null; | |
| } | |
| } | |
| @Override | |
| public int getItemCount() { | |
| return mObjects.size(); | |
| } | |
| public long getItemId(final int position) { | |
| return position; | |
| } | |
| /** | |
| * Returns the position of the specified item in the array. | |
| * | |
| * @param item The item to retrieve the position of. | |
| * @return The position of the specified item. | |
| */ | |
| public int getPosition(final T item) { | |
| return mObjects.indexOf(item); | |
| } | |
| /** | |
| * Removes the specified object from the array. | |
| * | |
| * @param object The object to remove. | |
| */ | |
| public void remove(T object) { | |
| final int position = getPosition(object); | |
| mObjects.remove(object); | |
| notifyItemRemoved(position); | |
| } | |
| public void removeLastObject() { | |
| mObjects.remove(mObjects.size() - 1); | |
| notifyItemRemoved(mObjects.size() - 1); | |
| } | |
| public void replaceItem(final T oldObject, final T newObject) { | |
| final int position = getPosition(oldObject); | |
| mObjects.remove(position); | |
| mObjects.add(position, newObject); | |
| notifyItemChanged(position); | |
| } | |
| public void replaceItemWithHeader(final T oldObject, final T newObject) { | |
| final int position = getPosition(oldObject); | |
| mObjects.remove(position); | |
| mObjects.add(position, newObject); | |
| notifyItemChanged(position + 1); | |
| } | |
| /** | |
| * Removes all elements and replaces them with the given guys from the list, all done with an | |
| * animation. | |
| * | |
| * @param objects The new Objects to display | |
| */ | |
| public void replaceObjectsWithAnimations(final List<T> objects) { | |
| animateRemoveObjects(objects); | |
| animateAddObjects(objects); | |
| } | |
| /** | |
| * Sorts the content of this adapter using the specified comparator. | |
| * | |
| * @param comparator The comparator used to sort the objects contained in this adapter. | |
| */ | |
| public void sort(Comparator<? super T> comparator) { | |
| Collections.sort(mObjects, comparator); | |
| notifyItemRangeChanged(0, getItemCount()); | |
| } | |
| /** | |
| * replaces the data with the given list | |
| * | |
| * @param objects new data | |
| */ | |
| public void swap(final List<T> objects) { | |
| swap(objects, new StableIdProvider<T>() { | |
| @Override | |
| public Object getId(final T item) { | |
| // id is unknown, at least return the item itself as id so it doesn't get | |
| // notified when it doesn't change at all. | |
| return item; | |
| } | |
| }); | |
| } | |
| /** | |
| * replaces the data with the given list | |
| * | |
| * @param newObjects new data | |
| * @param idProvider function to determine an identification for each element to detect same | |
| * (but updated) items | |
| */ | |
| public void swap(final List<T> newObjects, final StableIdProvider<T> idProvider) { | |
| DiffUtil.DiffResult result = DiffUtil.calculateDiff(new DiffUtil.Callback() { | |
| @Override | |
| public boolean areContentsTheSame(final int oldItemPosition, | |
| final int newItemPosition) { | |
| final T oldItem = mObjects.get(oldItemPosition); | |
| final T newItem = newObjects.get(newItemPosition); | |
| return (oldItem == newItem) || (oldItem != null && oldItem.equals(newItem)); | |
| } | |
| @Override | |
| public boolean areItemsTheSame(final int oldItemPosition, final int newItemPosition) { | |
| final T oldItem = mObjects.get(oldItemPosition); | |
| final T newItem = newObjects.get(newItemPosition); | |
| if (oldItem == null && newItem == null) { | |
| return true; | |
| } | |
| if (oldItem == null || newItem == null) { | |
| return false; | |
| } | |
| final Object oldId = idProvider.getId(oldItem); | |
| final Object newId = idProvider.getId(newItem); | |
| return (oldId == newId) || (oldId != null && oldId.equals(newId)); | |
| } | |
| @Override | |
| public int getNewListSize() { | |
| return newObjects != null ? newObjects.size() : 0; | |
| } | |
| @Override | |
| public int getOldListSize() { | |
| return mObjects != null ? mObjects.size() : 0; | |
| } | |
| }); | |
| mObjects = newObjects; | |
| result.dispatchUpdatesTo(this); | |
| } | |
| protected T removeItem(final int position) { | |
| final T object = mObjects.remove(position); | |
| notifyItemRemoved(position); | |
| return object; | |
| } | |
| protected T removeItemWithHeader(final int position) { | |
| final T object = mObjects.remove(position); | |
| notifyItemRemoved(position + 1); | |
| return object; | |
| } | |
| private void animateAddObjects(final List<T> objects) { | |
| for (int i = 0; i < objects.size(); i++) { | |
| final T object = objects.get(i); | |
| if (!mObjects.contains(object)) { | |
| addItem(object); | |
| } | |
| } | |
| } | |
| private void animateRemoveObjects(final List<T> objects) { | |
| for (int i = mObjects.size() - 1; i >= 0; i--) { | |
| final T object = mObjects.get(i); | |
| if (!objects.contains(object)) { | |
| removeItem(i); | |
| } | |
| } | |
| } | |
| private void moveItem(final int fromPosition, final int toPosition) { | |
| final T object = mObjects.remove(fromPosition); | |
| mObjects.add(toPosition, object); | |
| notifyItemMoved(fromPosition, toPosition); | |
| } | |
| } |