/** * Registers all of the contents in the specified type pool. If you have registered a * class, it will override the original binder(s). Note that the method is non-thread-safe * so that you should not use it in concurrent operation. * <p> * Note that the method should not be called after * {@link RecyclerView#setAdapter(RecyclerView.Adapter)}, or you have to call the setAdapter * again. * </p> * * @param pool type pool containing contents to be added to this adapter inner pool * @see #register(Class, ItemViewBinder) * @see #register(Class) */ public void registerAll(@NonNull final TypePool pool) { checkNotNull(pool); final int size = pool.size(); for (int i = 0; i < size; i++) { registerWithoutChecking( pool.getClass(i), pool.getItemViewBinder(i), pool.getLinker(i) ); } }
int indexInTypesOf(int position, @NonNull Object item) throws BinderNotFoundException { int index = typePool.firstIndexOf(item.getClass()); if (index != -1) { @SuppressWarnings("unchecked") Linker<Object> linker = (Linker<Object>) typePool.getLinker(index); return index + linker.index(position, item); } throw new BinderNotFoundException(item.getClass()); }
<T> void register( @NonNull Class<? extends T> clazz, @NonNull ItemViewBinder<T, ?> binder, @NonNull Linker<T> linker) { typePool.register(clazz, binder, linker); binder.adapter = this; }
@Test public void shouldOverrideRegisteredBinder() { MultiTypeAdapter adapter = new MultiTypeAdapter(); adapter.register(TestItem.class, itemViewBinder); assertEquals(1, adapter.getTypePool().size()); assertEquals(itemViewBinder, adapter.getTypePool().getItemViewBinder(0)); TestItemViewBinder newBinder = new TestItemViewBinder(); adapter.register(TestItem.class, newBinder); assertEquals(newBinder, adapter.getTypePool().getItemViewBinder(0)); }
@Test public void shouldNotOverrideRegisteredBinderWhenToMany() { MultiTypeAdapter adapter = new MultiTypeAdapter(); TestItemViewBinder binder2 = new TestItemViewBinder(); adapter.register(TestItem.class) .to(itemViewBinder, binder2) .withLinker(new Linker<TestItem>() { @Override public int index(int position, @NonNull TestItem testItem) { // ignored return -1; } }); assertEquals(TestItem.class, adapter.getTypePool().getClass(0)); assertEquals(TestItem.class, adapter.getTypePool().getClass(1)); assertEquals(itemViewBinder, adapter.getTypePool().getItemViewBinder(0)); assertEquals(binder2, adapter.getTypePool().getItemViewBinder(1)); }
@Override public final ViewHolder onCreateViewHolder(ViewGroup parent, int indexViewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); ItemViewBinder<?, ?> binder = typePool.getItemViewBinder(indexViewType); return binder.onCreateViewHolder(inflater, parent); }
private void checkAndRemoveAllTypesIfNeeded(@NonNull Class<?> clazz) { if (typePool.unregister(clazz)) { Log.w(TAG, "You have registered the " + clazz.getSimpleName() + " type. " + "It will override the original binder(s)."); } }
private @NonNull ItemViewBinder getRawBinderByViewHolder(@NonNull ViewHolder holder) { return typePool.getItemViewBinder(holder.getItemViewType()); }
@Override @SuppressWarnings("unchecked") public final void onBindViewHolder(ViewHolder holder, int position, @NonNull List<Object> payloads) { Object item = items.get(position); ItemViewBinder binder = typePool.getItemViewBinder(holder.getItemViewType()); binder.onBindViewHolder(holder, item, payloads); }
/** * Called to return the stable ID for the item, and passes the event to its associated binder. * * @param position Adapter position to query * @return the stable ID of the item at position * @see ItemViewBinder#getItemId(Object) * @see RecyclerView.Adapter#setHasStableIds(boolean) * @since v3.2.0 */ @Override @SuppressWarnings("unchecked") public final long getItemId(int position) { Object item = items.get(position); int itemViewType = getItemViewType(position); ItemViewBinder binder = typePool.getItemViewBinder(itemViewType); return binder.getItemId(item); }