26
DiUtil ŽELJKO PLESAC

Infinum Android Talks #20 - DiffUtil

  • Upload
    infinum

  • View
    149

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Infinum Android Talks #20 - DiffUtil

DiffUtil

ŽELJKO PLESAC

Page 2: Infinum Android Talks #20 - DiffUtil

TASK : UPDATE THE RECYCLER VIEW’S CONTENT.

Page 3: Infinum Android Talks #20 - DiffUtil

Sounds like an easy task…

Page 4: Infinum Android Talks #20 - DiffUtil

1. MISSING APIS

Page 5: Infinum Android Talks #20 - DiffUtil

RecyclerAdapter doesn’t have ArrayAdapter’s like methods -

add(), addAll(), remove(), clear()…

MISSING APIS

Page 6: Infinum Android Talks #20 - DiffUtil

DEFINE CUSTOM RECYCLER ADAPTER.

Page 7: Infinum Android Talks #20 - DiffUtil

private List<E> items;

public void add(E item) {…}public void addAll(Collection<E> collection) {…}public void add(E item, int index) {…}public void addAll(Collection<E> collection, int index) {…} public void remove(E item) {…} public void removeAll(Collection<E> collection) {…} public void remove(int index) {…}

public void clear() {…}

Page 8: Infinum Android Talks #20 - DiffUtil

Can add and remove items from adapter!

Page 9: Infinum Android Talks #20 - DiffUtil

2. UPDATE THE CONTENT OF AN ADAPTER.

Page 10: Infinum Android Talks #20 - DiffUtil

We need to manually fetch the correct item from adapter and

update it’s content.

Need to handle edge cases - what happens if item is not

presented in adapter?

Blocks the UI thread.

PROBLEMS WITH UPDATE

Page 11: Infinum Android Talks #20 - DiffUtil

DIFF UTIL TO THE RESCUE.

Page 12: Infinum Android Talks #20 - DiffUtil

Utility class that can calculate the difference between two lists

and output a list of update operations that converts the first

list into the second one.

DIFF UTIL

Page 13: Infinum Android Talks #20 - DiffUtil

Uses Myers's difference algorithm to calculate the minimal

number of updates to convert one list into another.

Myers's algorithm does not handle items that are moved so

DiffUtil runs a second pass on the result to detect items that

were moved.

DIFF UTIL

Page 14: Infinum Android Talks #20 - DiffUtil

If the lists are large, this operation may take significant time.

Use it on a background thread.

DIFF UTIL

Page 15: Infinum Android Talks #20 - DiffUtil
Page 16: Infinum Android Talks #20 - DiffUtil

public class SportsBookDiffUtils extends DiffUtil.Callback {

… @Nullable @Override public Object getChangePayload(int oldItemPosition, int newItemPosition) { Bundle bundle = new Bundle(); bundle.putInt(EXTRA_NUMBER_OF_EVENTS, newList.get(newItemPosition).getEventCount()); return bundle; } @Override public int getOldListSize() { return oldList != null ? oldList.size() : 0; } @Override public int getNewListSize() { return newList != null ? newList.size() : 0; } @Override public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { return newList.get(newItemPosition).getSportId() == oldList.get(oldItemPosition).getSportId(); } @Override public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { return newList.get(newItemPosition).getEventCount() == oldList.get(oldItemPosition).getEventCount(); }}

Page 17: Infinum Android Talks #20 - DiffUtil

DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new SportsBookDiffUtils(oldSports, newSports));diffResult.dispatchUpdatesTo(sportsAdapter);

Page 18: Infinum Android Talks #20 - DiffUtil

@Overridepublic void onBindViewHolder(MjolnirRecyclerAdapter<Sport>.ViewHolder holder, int position, List<Object> payloads) { if (!payloads.isEmpty()) { Bundle bundle = (Bundle) payloads.get(0); int eventCount = bundle.getInt(SportsBookDiffUtils.EXTRA_NUMBER_OF_EVENTS, 1); eventsTextView.setText(String.format( SettingsUtils.getLocale(), getContext().getString(R.string.events_format), eventCount)); } else { eventsTextView.setText(String.format( SettingsUtils.getLocale(), getContext().getString(R.string.events_format), get(position).getEventCount()) ); } }

Page 19: Infinum Android Talks #20 - DiffUtil

Can add, remove and update the content!

Page 20: Infinum Android Talks #20 - DiffUtil

It will block the UI (calculate the result on background thread

and, update on main).

Actual runtime of the algorithm significantly depends on the

number of changes in the list and the cost of your comparison

methods (more here).

Due to implementation constraints, the max size of the list can

be 2^26.

DRAWBACKS?

Page 21: Infinum Android Talks #20 - DiffUtil

BONUS

Page 22: Infinum Android Talks #20 - DiffUtil

INFINUM REINVENTS THE RECYCLER VIEW

Page 23: Infinum Android Talks #20 - DiffUtil
Page 24: Infinum Android Talks #20 - DiffUtil

ONE RECYCLER VIEW TO RULE THEM ALL

Page 25: Infinum Android Talks #20 - DiffUtil

Provides a simple way to extend the default RecyclerView

behaviour with support for headers, footers, empty view,

DiffUtil and ArrayAdapter like methods.

Open sourced until Ragnarök.

MJOLNIR RECYCLERVIEW

Page 26: Infinum Android Talks #20 - DiffUtil

Thank you!

Visit www.infinum.co or find us on social networks:

infinum.co infinumco infinumco infinum

@ZELJKOPLESAC [email protected]