Skip to content

Instantly share code, notes, and snippets.

Last active August 4, 2017 13:43
  • Star 19 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
Make your multiple type view adapter with annotations! Gist for

Make your multiple type view adapter with annotations!

Gist for Making a Multiple View Types Adapter With Annotations

Pretty easy to use.

  1. Create your delegate adapters, implementing DelegateAdapter, and with the annotation DelegateAdapterType. e.g:
@DelegateAdapterType(itemType = 0)
public class SimpleTextDelegateAdapter implements DelegateAdapter { ... getView() ... }
  1. Your main adapter have to extend the DispatcherAdapter. You will have to override getItemViewType add your delegateAdapters in the DelegateAdaptersAnnotation just like this:
@DelegateAdapters(delegateAdapters = {
public class MyAdapter extends DispatcherAdapter{ ... }
  1. You're done!

You can improve this gist/lib. We can imagine for example a wrapper class containing all the delegates, and an annotation DelegateAdapterWrapper(Class) for the DispatcherAdapter, so we only pass one the wrapper as parameter. Then if you have to add a new view type for your list, the only thing you have to do is add it in the wrapper class! Pretty handy no?

* You have to implement this interface for your delegates.
public interface DelegateAdapter {
public View getView(int position, View convertView, ViewGroup parent, LayoutInflater inflater, Object item);
public @interface DelegateAdaptersAnnotation {
Class<? extends DelegateAdapter>[] delegateAdapters();
public @interface DelegateAdapterType {
long itemType();
* Your custom adapter should extends this class
public abstract class DispatcherAdapter extends BaseAdapter {
private LongSparseArray<DelegateAdapter> mDelegateAdapterSparseArray;
protected Context mContext;
protected LayoutInflater mLayoutInflater;
public DispatcherAdapter(Context context) {
mContext = context;
mLayoutInflater = LayoutInflater.from(context);
* Init the delegates here, with reflection
private void initDelegates() {
mDelegateAdapterSparseArray = new LongSparseArray<DelegateAdapter>();
DelegateAdaptersAnnotation annotation = getClass().getAnnotation(DelegateAdaptersAnnotation.class);
if (annotation != null) {
Class[] clazzs = annotation.delegateAdapters();
if (clazzs != null) {
for (Class<?> clazz : clazzs) {
if (!DelegateAdapter.class.isAssignableFrom(clazz)) {
throw new RuntimeException("The class " + clazz.getName() + " is not a subclass of " + DelegateAdapter.class.getName());
DelegateAdapterType delegateAdapterType = clazz.getAnnotation(DelegateAdapterType.class);
if(delegateAdapterType == null){
throw new RuntimeException("The class "+clazz.getName()+" should have the annotation DelegateAdapterField");
long itemtype = delegateAdapterType.itemType();
if(mDelegateAdapterSparseArray.get(itemtype) != null){
throw new RuntimeException("The item type "+itemtype+" is already defined!");
DelegateAdapter adapter = null;
try {
adapter = (DelegateAdapter) clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException("Error while instanciating "+clazz.getName()+" with default constructor: "+e.getMessage(), e);
mDelegateAdapterSparseArray.put(itemtype, adapter);
public View getView(int position, View convertView, ViewGroup parent) {
long itemtype = getItemViewType(position);
DelegateAdapter delegateAdapter = mDelegateAdapterSparseArray.get(itemtype);
if(delegateAdapter == null){
throw new RuntimeException("Unknown type "+itemtype+" called");
return mDelegateAdapterSparseArray.get(itemtype).getView(position, convertView, parent, mLayoutInflater, getItem(position));
public int getViewTypeCount() {
return mDelegateAdapterSparseArray.size();
Copy link

can you make a working example of this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment