Last active
September 13, 2015 00:48
-
-
Save shayousefi/e2952ab636f6ce593ff2 to your computer and use it in GitHub Desktop.
A RecyclerView adapter backed by a list.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2015 Shahin Yousefi | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
/** | |
* An {@code RecyclerView.Adapter} backed by a {@link List}. | |
* | |
* @param <VH> type of {@code RecyclerView.ViewHolder} | |
* @param <E> type of list element | |
*/ | |
public abstract class ListRecyclerAdapter<VH extends RecyclerView.ViewHolder, E> | |
extends RecyclerView.Adapter<VH> { | |
protected List<E> list; | |
public ListRecyclerAdapter() { | |
list = Collections.synchronizedList(new LinkedList<E>()); | |
} | |
public ListRecyclerAdapter(@NonNull Collection<? extends E> items) { | |
list = Collections.synchronizedList(new LinkedList<>(items)); | |
} | |
@Override | |
public int getItemCount() { | |
return list.size(); | |
} | |
/** | |
* Adds the specified item at the end of the underlying list, | |
* and notifies any registered observers. | |
* | |
* @param item the item to add | |
*/ | |
public void addItem(E item) { | |
addItem(list.size(), item); | |
} | |
/** | |
* Inserts the specified item into the underlying list at the specified location, | |
* and notifies any registered observers. | |
* | |
* @param position the index at which to insert | |
* @param item the item to add | |
*/ | |
public void addItem(int position, E item) { | |
list.add(position, item); | |
notifyItemInserted(position); | |
} | |
/** | |
* Adds the items in the specified collection to the end of the underlying list, | |
* and notifies any registered observers. | |
* | |
* @param items the collection of items | |
*/ | |
public void addAllItems(@NonNull Collection<? extends E> items) { | |
addAllItems(list.size(), items); | |
} | |
/** | |
* Inserts the items in the specified collection at the specified location in | |
* the underlying list, and notifies any registered observers. | |
* | |
* @param startPosition the index at which to start inserting items | |
* @param items the collection of items to be inserted | |
*/ | |
public void addAllItems(int startPosition, @NonNull Collection<? extends E> items) { | |
if (list.addAll(startPosition, items)) { | |
notifyItemRangeInserted(startPosition, items.size()); | |
} | |
} | |
/** | |
* Removes all elements from the underlying list, leaving it empty, | |
* and notifies any registered observers. | |
*/ | |
public void clearItems() { | |
int itemCount = list.size(); | |
list.clear(); | |
notifyItemRangeRemoved(0, itemCount); | |
} | |
/** | |
* Tests whether the underlying list contains the specified item. | |
* | |
* @param item the item to search for | |
* @return {@code true} if item is an element of the underlying list, {@code false} otherwise. | |
*/ | |
public boolean containsItem(E item) { | |
return list.contains(item); | |
} | |
/** | |
* Tests whether the underlying list contains all items contained in the specified collection. | |
* | |
* @param items the collection of items | |
* @return {@code true} if all items in the specified collection are elements of | |
* the underlying list, {@code false} otherwise. | |
*/ | |
public boolean containsAllItems(@NonNull Collection<? extends E> items) { | |
return list.containsAll(items); | |
} | |
/** | |
* Returns the element at the specified location in the underlying list. | |
* | |
* @param position the index of the element to return | |
* @return The element at the specified location. | |
*/ | |
public E getItem(int position) { | |
return list.get(position); | |
} | |
/** | |
* Returns an unmodifiable list of the specified portion of the underlying list. | |
* | |
* @param startPosition the index at which to start the sublist | |
* @param itemCount the number of items to include in the sublist | |
* @return An unmodifiable sublist of the underlying list. | |
*/ | |
public List<E> getItems(int startPosition, int itemCount) { | |
return Collections.unmodifiableList(list.subList(startPosition, startPosition + itemCount)); | |
} | |
/** Returns an unmodifiable list of all items in this adapter. */ | |
public List<E> getListItems() { | |
return Collections.unmodifiableList(list); | |
} | |
/** | |
* Searches the underlying list for the specified item and returns the index of | |
* the first occurrence. | |
* | |
* @param item the item to search for | |
* @return The index of the first occurrence of the item or -1 if the item was not found. | |
*/ | |
public int indexOf(E item) { | |
return list.indexOf(item); | |
} | |
/** | |
* Returns whether the underlying list contains no elements. | |
* | |
* @return {@code true} if the underlying list has no elements, {@code false} otherwise. | |
*/ | |
public boolean isEmpty() { | |
return list.isEmpty(); | |
} | |
/** | |
* Searches the underlying list for the specified item and returns the index of | |
* the last occurrence. | |
* | |
* @param item the item to search for | |
* @return The index of the last occurrence of the item, or -1 if the item was not found. | |
*/ | |
public int lastIndexOf(E item) { | |
return list.lastIndexOf(item); | |
} | |
/** | |
* Moves the item at {@code fromPosition} to {@code toPosition} in the underlying list. | |
* | |
* @param fromPosition previous position of the item | |
* @param toPosition new position of the item | |
*/ | |
public void moveItem(int fromPosition, int toPosition) { | |
if (fromPosition != toPosition) { | |
list.add(toPosition, list.remove(fromPosition)); | |
notifyItemMoved(fromPosition, toPosition); | |
} | |
} | |
/** | |
* Removes the item at the specified location from the underlying list, | |
* and notifies any registered observers. | |
* | |
* @param position the index of the item to remove | |
* @return The removed item. | |
*/ | |
public E removeItem(int position) { | |
E item = list.remove(position); | |
notifyItemRemoved(position); | |
return item; | |
} | |
/** | |
* Removes the first occurrence of the specified item from the underlying list, | |
* and notifies any registered observers. | |
* | |
* @param item the item to remove | |
*/ | |
public void removeItem(E item) { | |
int position = list.indexOf(item); | |
if (position >= 0 && list.remove(item)) { | |
notifyItemRemoved(position); | |
} | |
} | |
/** | |
* Removes the specified portion of the underlying list. | |
* | |
* @param startPosition the index at which to start removing items | |
* @param itemCount the number of items to remove | |
*/ | |
public void removeItems(int startPosition, int itemCount) { | |
list.subList(startPosition, startPosition + itemCount).clear(); | |
notifyItemRangeRemoved(startPosition, itemCount); | |
} | |
/** | |
* Removes all occurrences in the underlying list of each item in the specified collection, | |
* and notifies any registered observers. | |
* | |
* @param items the collection of items to remove | |
*/ | |
public void removeAllItems(@NonNull Collection<? extends E> items) { | |
if (list.removeAll(items)) { | |
notifyDataSetChanged(); | |
} | |
} | |
/** | |
* Removes all items from the underlying list that are not contained in | |
* the specified collection, and notifies any registered observers. | |
* | |
* @param items the collection of items to retain | |
*/ | |
public void retainAllItems(@NonNull Collection<? extends E> items) { | |
if (list.retainAll(items)) { | |
notifyDataSetChanged(); | |
} | |
} | |
/** | |
* Replaces the element at the specified location in the underlying list with | |
* the specified item, and notifies any registered observers. | |
* | |
* @param position the index at which to put the specified item | |
* @param item the item to insert | |
* @return The previous element at the index. | |
*/ | |
public E setItem(int position, E item) { | |
E oldItem = list.set(position, item); | |
notifyItemChanged(position); | |
return oldItem; | |
} | |
/** | |
* Replaces the items at the specified portion of the underlying list with items | |
* from the given collection, and notifies any registered observers. | |
* | |
* @param startPosition the index at which to start replacing items | |
* @param items the collection of items to replace existing items with | |
* @return An unmodifiable list of the replaced items. | |
*/ | |
public List<E> setAllItems(int startPosition, @NonNull Collection<? extends E> items) { | |
int itemCount = items.size(); | |
List<E> oldItems = new ArrayList<>(itemCount); | |
List<E> sublist = list.subList(startPosition, startPosition + itemCount); | |
int i = 0; | |
for (E item : items) { | |
oldItems.add(sublist.set(i, item)); | |
i++; | |
} | |
notifyItemRangeChanged(startPosition, itemCount); | |
return Collections.unmodifiableList(oldItems); | |
} | |
/** | |
* Repopulates the underlying list with items from the specified collection, | |
* and notifies any registered observers. | |
* | |
* @param items the collection of items to insert to a fresh list | |
*/ | |
public void setListItems(@NonNull Collection<? extends E> items) { | |
int itemCount = list.size(); | |
list.clear(); | |
if (list.addAll(items)) { | |
notifyDataSetChanged(); | |
} else { | |
notifyItemRangeRemoved(0, itemCount); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment