Skip to content

Instantly share code, notes, and snippets.

@TedaLIEz
Last active September 26, 2016 09:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TedaLIEz/3e1ee88b0daf962d89cbf56cb26d1f8f to your computer and use it in GitHub Desktop.
Save TedaLIEz/3e1ee88b0daf962d89cbf56cb26d1f8f to your computer and use it in GitHub Desktop.
My implementation of multiple type in RecyclerView.Adapter, refering to https://medium.com/@dpreussler/writing-better-adapters-1b09758407d2#.dsmf2nwjg, how to avoid if-else in onCreateViewHolder method?
package com.example.jianguo.handlertest.adapters;
/**
* Created by JianGuo on 9/26/16.
* interface for all kinds of animals.
*/
public interface Animal extends Visitable {
String say();
}
package com.example.jianguo.handlertest.adapters;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* Created by JianGuo on 9/26/16.
* Base Viewholder
*/
public abstract class BaseViewHolder<T extends Animal> extends RecyclerView.ViewHolder {
public BaseViewHolder(View itemView) {
super(itemView);
}
abstract void bind(T item);
}
package com.example.jianguo.handlertest.adapters;
/**
* Created by JianGuo on 9/26/16.
*/
public class Cat implements Animal {
@Override
public String say() {
return "I'm a cat";
}
@Override
public int type(TypeFactory typeFactory) {
return typeFactory.type(this);
}
}
package com.example.jianguo.handlertest.adapters;
import android.view.View;
import android.widget.TextView;
import com.example.jianguo.handlertest.R;
/**
* Created by JianGuo on 9/26/16.
* {@link android.support.v7.widget.RecyclerView.ViewHolder} for {@link Cat}
*/
public class CatViewHolder extends BaseViewHolder<Cat> {
public CatViewHolder(View itemView) {
super(itemView);
}
@Override
void bind(Cat item) {
TextView tv = (TextView) itemView.findViewById(R.id.item_cat);
tv.setText(item.say());
}
}
package com.example.jianguo.handlertest.adapters;
/**
* Created by JianGuo on 9/26/16.
*/
public class Mouse implements Animal {
@Override
public String say() {
return "I'm a mouse";
}
@Override
public int type(TypeFactory typeFactory) {
return typeFactory.type(this);
}
}
package com.example.jianguo.handlertest.adapters;
import android.view.View;
import android.widget.TextView;
import com.example.jianguo.handlertest.R;
/**
* Created by JianGuo on 9/26/16.
* {@link android.support.v7.widget.RecyclerView.ViewHolder} for {@link Mouse}
*/
public class MouseViewHolder extends BaseViewHolder<Mouse> {
public MouseViewHolder(View itemView) {
super(itemView);
}
@Override
void bind(Mouse item) {
TextView tv = (TextView) itemView.findViewById(R.id.item_mouse);
tv.setText(item.say());
}
}
package com.example.jianguo.handlertest.adapters;
/**
* Created by JianGuo on 9/26/16.
* Factory interface for type.
*/
public interface TypeFactory {
int type(Mouse mouse);
int type(Cat cat);
}
package com.example.jianguo.handlertest.adapters;
/**
* Created by JianGuo on 9/26/16.
*/
public class TypeFactoryImpl implements TypeFactory {
@Override
public int type(Mouse mouse) {
return mouse.getClass().hashCode();
}
@Override
public int type(Cat cat) {
return cat.getClass().hashCode();
}
}
package com.example.jianguo.handlertest.adapters;
import android.support.v4.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
/**
* Created by JianGuo on 9/26/16.
* Factory for ViewHolder
*/
public class ViewHolderProvider {
private static Map<Integer, Pair<Integer, Class<? extends BaseViewHolder>>> viewHolderFactories = new HashMap<>();
static BaseViewHolder provideViewHolder(ViewGroup parent, int viewType) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
View view = LayoutInflater.from(parent.getContext()).inflate(viewHolderFactories.get(viewType).first, parent, false);
Constructor<? extends BaseViewHolder> constructor = viewHolderFactories.get(viewType).second.getConstructor(View.class);
return constructor.newInstance(view);
}
static void registerViewHolderFactory(int viewType, Pair<Integer, Class<? extends BaseViewHolder>> pair) {
viewHolderFactories.put(viewType, pair);
}
}
package com.example.jianguo.handlertest.adapters;
/**
* Created by JianGuo on 9/26/16.
* Basic interface for visitor-pattern
*/
public interface Visitable {
int type(TypeFactory typeFactory);
}
package com.example.jianguo.handlertest.adapters;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.util.Pair;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
import com.example.jianguo.handlertest.R;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
/**
* Created by JianGuo on 9/26/16.
* Implementation of {@link android.support.v7.widget.RecyclerView.Adapter} for visitor-pattern.
*/
public class VisitableAdapter extends RecyclerView.Adapter<BaseViewHolder> {
private List<Animal> mData;
private Context mContext;
public VisitableAdapter(@NonNull Context context, @NonNull List<Animal> data) {
mContext = context;
mData = data;
ViewHolderProvider.registerViewHolderFactory(Mouse.class.hashCode(),
new Pair<Integer, Class<? extends BaseViewHolder>>(R.layout.mouse,
MouseViewHolder.class));
ViewHolderProvider.registerViewHolderFactory(Cat.class.hashCode(),
new Pair<Integer, Class<? extends BaseViewHolder>>(R.layout.cat,
CatViewHolder.class));
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
try {
return ViewHolderProvider.provideViewHolder(parent, viewType);
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
throw new IllegalArgumentException("Unsupported viewType: " + viewType);
}
}
@Override
@SuppressWarnings("unchecked")
public void onBindViewHolder(BaseViewHolder holder, int position) {
holder.bind(mData.get(position));
}
@Override
public int getItemViewType(int position) {
return mData.get(position).type(new TypeFactoryImpl());
}
@Override
public int getItemCount() {
return mData.size();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment