public class SortedList<T> extends Object
RecyclerView.Adapter
.
It keeps items ordered using the SortedList.Callback.compare(Object, Object)
method and uses
binary search to retrieve items. If the sorting criteria of your items may change, make sure you
call appropriate methods while editing them to avoid data inconsistencies.
You can control the order of items and change notifications via the SortedList.Callback
parameter.
Modifier and Type | Class and Description |
---|---|
static class |
SortedList.BatchedCallback<T2>
A callback implementation that can batch notify events dispatched by the SortedList.
|
static class |
SortedList.Callback<T2>
The class that controls the behavior of the
SortedList . |
Modifier and Type | Field and Description |
---|---|
static int |
INVALID_POSITION
Used by
indexOf(Object) when he item cannot be found in the list. |
Constructor and Description |
---|
SortedList(Class<T> klass,
SortedList.Callback<T> callback)
Creates a new SortedList of type T.
|
SortedList(Class<T> klass,
SortedList.Callback<T> callback,
int initialCapacity)
Creates a new SortedList of type T.
|
Modifier and Type | Method and Description |
---|---|
int |
add(T item)
Adds the given item to the list.
|
void |
addAll(Collection<T> items)
Adds the given items to the list.
|
void |
addAll(T... items)
Adds the given items to the list.
|
void |
addAll(T[] items,
boolean mayModifyInput)
Adds the given items to the list.
|
void |
beginBatchedUpdates()
Batches adapter updates that happen between calling this method until calling
endBatchedUpdates() . |
void |
clear()
Removes all items from the SortedList.
|
void |
endBatchedUpdates()
Ends the update transaction and dispatches any remaining event to the callback.
|
T |
get(int index)
Returns the item at the given index.
|
int |
indexOf(T item)
Returns the position of the provided item.
|
void |
recalculatePositionOfItemAt(int index)
This method can be used to recalculate the position of the item at the given index, without
triggering an
SortedList.Callback.onChanged(int, int) callback. |
boolean |
remove(T item)
Removes the provided item from the list and calls
ListUpdateCallback.onRemoved(int, int) . |
T |
removeItemAt(int index)
Removes the item at the given index and calls
ListUpdateCallback.onRemoved(int, int) . |
int |
size()
The number of items in the list.
|
void |
updateItemAt(int index,
T item)
Updates the item at the given index and calls
SortedList.Callback.onChanged(int, int) and/or
ListUpdateCallback.onMoved(int, int) if necessary. |
public static final int INVALID_POSITION
indexOf(Object)
when he item cannot be found in the list.public SortedList(Class<T> klass, SortedList.Callback<T> callback)
klass
- The class of the contents of the SortedList.callback
- The callback that controls the behavior of SortedList.public SortedList(Class<T> klass, SortedList.Callback<T> callback, int initialCapacity)
klass
- The class of the contents of the SortedList.callback
- The callback that controls the behavior of SortedList.initialCapacity
- The initial capacity to hold items.public int size()
public int add(T item)
ListUpdateCallback.onInserted(int, int)
.
If the item already exists in the list and its sorting criteria is not changed, it is
replaced with the existing Item. SortedList uses
SortedList.Callback.areItemsTheSame(Object, Object)
to check if two items are the same item
and uses SortedList.Callback.areContentsTheSame(Object, Object)
to decide whether it should
call SortedList.Callback.onChanged(int, int)
or not. In both cases, it always removes the
reference to the old item and puts the new item into the backing array even if
SortedList.Callback.areContentsTheSame(Object, Object)
returns false.
If the sorting criteria of the item is changed, SortedList won't be able to find
its duplicate in the list which will result in having a duplicate of the Item in the list.
If you need to update sorting criteria of an item that already exists in the list,
use updateItemAt(int, Object)
. You can find the index of the item using
indexOf(Object)
before you update the object.
item
- The item to be added into the list.Callback#compare(Object, Object)}
,
Callback#areItemsTheSame(Object, Object)}
,
Callback#areContentsTheSame(Object, Object)}}
public void addAll(T[] items, boolean mayModifyInput)
add(T)
in a loop,
except the callback events may be in a different order/granularity since addAll can batch
them for better performance.
If allowed, may modify the input array and even take the ownership over it in order to avoid extra memory allocation during sorting and deduplication.
items
- Array of items to be added into the list.mayModifyInput
- If true, SortedList is allowed to modify the input.SortedList#addAll(Object[] items)}.
public void addAll(T... items)
items
- Array of items to be added into the list.SortedList#addAll(T[] items, boolean mayModifyInput)}
public void addAll(Collection<T> items)
items
- Collection of items to be added into the list.SortedList#addAll(T[] items, boolean mayModifyInput)}
public void beginBatchedUpdates()
endBatchedUpdates()
. For example, if you add multiple items in a loop
and they are placed into consecutive indices, SortedList calls
ListUpdateCallback.onInserted(int, int)
only once with the proper item count. If an event
cannot be merged with the previous event, the previous event is dispatched
to the callback instantly.
After running your data updates, you must call endBatchedUpdates()
which will dispatch any deferred data change event to the current callback.
A sample implementation may look like this:
mSortedList.beginBatchedUpdates(); try { mSortedList.add(item1) mSortedList.add(item2) mSortedList.remove(item3) ... } finally { mSortedList.endBatchedUpdates(); }
Instead of using this method to batch calls, you can use a Callback that extends
SortedList.BatchedCallback
. In that case, you must make sure that you are manually calling
SortedList.BatchedCallback.dispatchLastEvent()
right after you complete your data changes.
Failing to do so may create data inconsistencies with the Callback.
If the current Callback in an instance of SortedList.BatchedCallback
, calling this method
has no effect.
public void endBatchedUpdates()
public boolean remove(T item)
ListUpdateCallback.onRemoved(int, int)
.item
- The item to be removed from the list.public T removeItemAt(int index)
ListUpdateCallback.onRemoved(int, int)
.index
- The index of the item to be removed.public void updateItemAt(int index, T item)
SortedList.Callback.onChanged(int, int)
and/or
ListUpdateCallback.onMoved(int, int)
if necessary.
You can use this method if you need to change an existing Item such that its position in the list may change.
If the new object is a different object (get(index) != item
) and
SortedList.Callback.areContentsTheSame(Object, Object)
returns true
, SortedList
avoids calling SortedList.Callback.onChanged(int, int)
otherwise it calls
SortedList.Callback.onChanged(int, int)
.
If the new position of the item is different than the provided index
,
SortedList
calls ListUpdateCallback.onMoved(int, int)
.
index
- The index of the item to replaceitem
- The item to replace the item at the given Index.add(Object)
public void recalculatePositionOfItemAt(int index)
SortedList.Callback.onChanged(int, int)
callback.
If you are editing objects in the list such that their position in the list may change but
you don't want to trigger an onChange animation, you can use this method to re-position it.
If the item changes position, SortedList will call ListUpdateCallback.onMoved(int, int)
without
calling SortedList.Callback.onChanged(int, int)
.
A sample usage may look like:
final int position = mSortedList.indexOf(item); item.incrementPriority(); // assume items are sorted by priority mSortedList.recalculatePositionOfItemAt(position);In the example above, because the sorting criteria of the item has been changed, mSortedList.indexOf(item) will not be able to find the item. This is why the code above first gets the position before editing the item, edits it and informs the SortedList that item should be repositioned.
index
- The current index of the Item whose position should be re-calculated.updateItemAt(int, Object)
,
add(Object)
public T get(int index) throws IndexOutOfBoundsException
index
- The index of the item to retrieve.IndexOutOfBoundsException
- if provided index is negative or larger than the
size of the list.public int indexOf(T item)
item
- The item to query for position.INVALID_POSITION
if item is not in the
list.public void clear()