package com.badoo.chateau.extras.recycle; import android.support.annotation.NonNull; import android.support.v4.util.SparseArrayCompat; import android.support.v7.widget.RecyclerView; import android.view.ViewGroup; import java.util.HashMap; import java.util.Map; /** * Simple holder for {@link ViewHolderFactory}s to be used with and {@link android.support.v7.widget.RecyclerView.Adapter}. */ public class ViewHolderFactoryResolver<T extends RecyclerView.ViewHolder> { private final int mOffset; private final Map<Class<?>, ViewHolderFactoryWithId> mViewHolderCreatorsFromType = new HashMap<>(); private final SparseArrayCompat<ViewHolderFactory<? extends T>> mMessageViewHolderFactories = new SparseArrayCompat<>(); /** * Create with an offset of 0. */ public ViewHolderFactoryResolver() { this(0); } /** * Create with a given offset. The offset is use as the id of the first factory registered with subsequent factories given a and id * of offset + number of previous factories registered. */ public ViewHolderFactoryResolver(int offset) { mOffset = offset; } /** * Register a factory for a given type, returns the id for that factory. The id is generated sequentially from offset given in the * constructor in the order that the factories are registered (first factories id is offset, second is offset+1 etc). */ public int registerFactory(Class<?> type, ViewHolderFactory<? extends T> factory) { final int id = mMessageViewHolderFactories.size() + mOffset; mViewHolderCreatorsFromType.put(type, new ViewHolderFactoryWithId(id, factory)); mMessageViewHolderFactories.put(id, factory); return id; } /** * Lookup the id for a given type. */ public int getIdForType(Class<?> type) { final ViewHolderFactoryWithId viewHolderCreatorWithId = mViewHolderCreatorsFromType.get(type); if (viewHolderCreatorWithId == null) { throw new IllegalStateException("No view holder create registered for " + type); } return viewHolderCreatorWithId.getId(); } /** * Retrieve the factory for a given id */ public ViewHolderFactory<? extends T> getFactoryForId(int id) { if (id < mOffset || id > mOffset + mMessageViewHolderFactories.size()) { throw new IllegalArgumentException("No factory registered for view with id " + id); } return mMessageViewHolderFactories.get(id); } private class ViewHolderFactoryWithId implements ViewHolderFactory { private int mId; private final ViewHolderFactory mFactory; ViewHolderFactoryWithId(int id, ViewHolderFactory factory) { mId = id; mFactory = factory; } public int getId() { return mId; } @NonNull @Override public RecyclerView.ViewHolder create(@NonNull ViewGroup parent) { return mFactory.create(parent); } } }