public class TestAdapter extends RecyclerView.Adapter {
private List mData;
private static final int TEXT = 0;
private static final int AUDIO = 1;
private static final int IMAGE = 2;
public TestAdapter(List mData){
this.mData = mData;
}
@NonNull
@Override
public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup mViewGroup, int mI) {
BaseViewHolder baseViewHolder = null;
switch (mI){
case TEXT:
baseViewHolder = new TextViewHolder(LayoutInflater.from(mViewGroup.getContext()).inflate(R.layout.item_text,null));
break;
case AUDIO:
baseViewHolder = new AudioViewHoder(LayoutInflater.from(mViewGroup.getContext()).inflate(R.layout.item_text,null));
break;
case IMAGE:
baseViewHolder = new ImageViewHolder(LayoutInflater.from(mViewGroup.getContext()).inflate(R.layout.item_text,null));
break;
}
return baseViewHolder;
}
@Override
public void onBindViewHolder(@NonNull BaseViewHolder mBaseViewHolder, int mI) {
mBaseViewHolder.onBindViewHolder(mBaseViewHolder,mI);
}
@Override
public int getItemViewType(int position) {
int type = 0;
switch (mData.get(position).getType()){
case TEXT:
break;
case AUDIO:
type = 1;
break;
case IMAGE :
type = 2;
break;
}
return type;
}
@Override
public int getItemCount() {
return mData.size();
}
class AudioViewHoder extends BaseViewHolder{
public AudioViewHoder(@NonNull View itemView) {
super(itemView);
}
@Override
public void onBindViewHolder(@NonNull BaseViewHolder mBaseViewHolder, int mI) {
}
}
class ImageViewHolder extends BaseViewHolder{
public ImageViewHolder(@NonNull View itemView) {
super(itemView);
}
@Override
public void onBindViewHolder(@NonNull BaseViewHolder mBaseViewHolder, int mI) {
}
}
class TextViewHolder extends BaseViewHolder{
public TextViewHolder(@NonNull View itemView) {
super(itemView);
}
@Override
public void onBindViewHolder(@NonNull BaseViewHolder mBaseViewHolder, int mI) {
}
}
abstract class BaseViewHolder extends RecyclerView.ViewHolder{
public BaseViewHolder(@NonNull View itemView) {
super(itemView);
}
public abstract void onBindViewHolder(@NonNull BaseViewHolder mBaseViewHolder, int mI);
}
}
这是普通的写法,根据getItemViewType区分类型,在type类型不多的时候,这种写法是可取的,但像IM软件中消息列表type类型可达几十种,增加一种消息类型,则需要改动好几处地方,这有点不符合设计原则。而且也没有办法复用该adapter.
public abstract class IItemView {
private T mBaseAdapter;
public IItemView(T mBaseAdapter){
this.mBaseAdapter = mBaseAdapter;
}
public abstract int getLayoutId();
public abstract void onBindViewHolder(@NonNull BaseViewHolder mBaseViewHolder, int mI,K data);
}
该类用于不同类型item的创建以及数据绑定,也可以说是RecyclerView的ViewHolder。
public class ViewHoderFactory {
private static HashMap,Class extends IItemView>> viewHolders = new HashMap<>();
static {
register(TextBean.class,TextViewHolder.class);
register(AudioBean.class,AudioViewHoder.class);
register(ImageBean.class,ImageViewHolder.class);
}
public static void register(Class extends BaseBean> bean,Class extends IItemView> holder){
viewHolders.put(bean,holder);
}
public static Class extends IItemView> getViewHoderType(Class extends BaseBean> bean){
return viewHolders.get(bean);
}
public static List> getAllViewHoder(){
return new ArrayList<>(viewHolders.values());
}
}
该类比较明显,是一个IItemView (也就是ViewHolder)工厂类,用于不同类型的注册,然后用于在adapter中类型区分。
public abstract class BaseAdapter extends RecyclerView.Adapter {
private List extends BaseBean> mData;
private HashMap,Integer> mHashMap = new HashMap<>();
private SparseArray> holderClasses = new SparseArray<>();
public BaseAdapter(List extends BaseBean> mData){
this.mData = mData;
List> viewHolders = getIItemViewList();
for (int i=0;i viewClazz = holderClasses.get(mI);
Constructor constructor = viewClazz.getConstructors()[0];
IItemView iItemView = (IItemView) constructor.newInstance(getAdapter());
return new BaseViewHolder(LayoutInflater.from(mViewGroup.getContext()).inflate(iItemView.getLayoutId(),mViewGroup,false),iItemView,mData);
} catch (IllegalAccessException mE) {
mE.printStackTrace();
} catch (InstantiationException mE) {
mE.printStackTrace();
} catch (InvocationTargetException mE) {
mE.printStackTrace();
}
return null;
}
@Override
public void onBindViewHolder(@NonNull BaseViewHolder mBaseViewHolder, int mI) {
mBaseViewHolder.onBindViewHolder(mBaseViewHolder,mI);
}
@Override
public int getItemViewType(int position) {
return mHashMap.get(ViewHoderFactory.getViewHoderType(mData.get(position).getClass()));
}
@Override
public int getItemCount() {
return mData.size();
}
protected abstract T getAdapter();
protected abstract List> getIItemViewList();
}
该类是一个抽象的adapter,需要新建一个类继承使用。在该adapter中使用ViewHolderFactory区分类型,以及使用反射创建IItemView,只需要在ViewHolderFactory中根据规则 注册不同类型的item,随意增加删减替换顺序都不会影响到adapter,不同类型
的item在各自的Holder中进行数据绑定,实现解耦。
优化后的adapter符合开闭设计原则,便于扩展以及复用。不过仍然还有比较明显的缺陷,也就是ViewHolderFactory,在复用的过程中,需要创建不同的ViewHolderFactory,还会导致静态对象越来越多,还需要进一步的优化。代码已上传github
https://github.com/onelunatic/recycleViewDemo