Given a stream of collection of items to show, provide a diff callback which determines the size and differences in that collection.
Observable<List<String>> observable1 ...;
observable1.compose(RxDiffUtil.diff(new RxDiffUtil.Callback<List<String>>() {
@Override
public int getSize(List<String> list) {
return list.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, List<String> oldItems, int newItemPosition, List<String> newItems) {
return oldItems.get(oldItemPosition).equals(newItems.get(newItemPosition));
}
@Override
public boolean areContentsTheSame(int oldItemPosition, List<String> oldItems, int newItemPosition, List<String> newItems) {
return true;
}
})).subscribe(result -> {
// This should be on the main thread. Update the adapter's list and dispatch the diff updates.
adapter.items = result.items;
result.diff.dispatchUpdatesTo(adapter);
});
If you know your collection is a List
, you can more convienetly just provide the item diffing logic.
Observable<List<String>> observable2 = ...;
observable2.compose(RxDiffUtil.diff(new RxDiffUtil.ListCallback<String>() {
@Override
public boolean areItemsTheSame(String oldItem, String newItem) {
return oldItem.equals(newItem);
}
@Override
public boolean areContentsTheSame(String oldItem, String newItem) {
return true;
}
})).subscribe(result -> {
adapter.items = result.items;
result.diff.dispatchUpdatesTo(adapter);
});
Alternativly, you can implement Diffable
on your items and provide the diff logic there.
isSame()
coresponds to areItemsTheSame()
and equals()
coresponds to areContentsTheSame()
.
public static class Foo implements RxDiffUtil.Diffable<Foo> {
private final int id;
private final String value;
public Foo(int id, String value) {
this.id = id;
this.value = value;
}
@Override
public boolean isSame(Foo other) {
return id == other.id;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + value.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Foo foo = (Foo) o;
if (id != foo.id) return false;
return value.equals(foo.value);
}
}
Observable<List<Foo>> observable3 ...;
observable3.compose(RxDiffUtil.<Foo>diff())
.subscribe(result -> {
adapter.items = result.items;
result.diff.dispatchUpdatesTo(adapter);
});
Feel free to run the diff on a background thread.
Observable<List<Foo>> observable3;
observable3
.observeOn(Schedulers.computation())
.compose(RxDiffUtil.<Foo>diff())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
adapter.items = result.items;
result.diff.dispatchUpdatesTo(adapter);
});