Skip to content

Instantly share code, notes, and snippets.

Last active August 4, 2017 13:43
Show Gist options
  • Save castorflex/5776863 to your computer and use it in GitHub Desktop.
Save castorflex/5776863 to your computer and use it in GitHub Desktop.
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