/** * Whether two item objects represent the same underlying data when compared using DiffUtil, * even if there has been a change in that data. * <p> * The default implementation compares both view type and id. */ public boolean isSameAs(Item other) { if (getLayout() != other.getLayout()) { return false; } return getId() == other.getId(); }
@Override public int getItemViewType(int position) { lastItemForViewTypeLookup = getItem(position); if (lastItemForViewTypeLookup == null) throw new RuntimeException("Invalid position " + position); return lastItemForViewTypeLookup.getLayout(); }
/** * This idea was copied from Epoxy. :wave: Bright idea guys! * <p> * Find the model that has the given view type so we can create a viewholder for that model. * <p> * To make this efficient, we rely on the RecyclerView implementation detail that {@link * GroupAdapter#getItemViewType(int)} is called immediately before {@link * GroupAdapter#onCreateViewHolder(android.view.ViewGroup, int)}. We cache the last model * that had its view type looked up, and unless that implementation changes we expect to have a * very fast lookup for the correct model. * <p> * To be safe, we fallback to searching through all models for a view type match. This is slow and * shouldn't be needed, but is a guard against RecyclerView behavior changing. */ private Item<VH> getItemForViewType(@LayoutRes int layoutResId) { if (lastItemForViewTypeLookup != null && lastItemForViewTypeLookup.getLayout() == layoutResId) { // We expect this to be a hit 100% of the time return lastItemForViewTypeLookup; } // To be extra safe in case RecyclerView implementation details change... for (int i = 0; i < getItemCount(); i++) { Item item = getItem(i); if (item.getLayout() == layoutResId) { return item; } } throw new IllegalStateException("Could not find model for view type: " + layoutResId); }