RecyclerView通用Adapter(MultiTypeItem)

通用的RecyclerView 的Adapter 多类型

都是从网上查来的,写到这里以后比较好找
多类型的适配器比单一类型的适配器多了一个多类型布局的创建和数据绑定时ItemType的辨别
先创建一个多类型的辅助类

import android.support.annotation.LayoutRes;

/**
 * Created by Song on 2019/7/19 10:52
 * I love you three thousand times.
 */
public abstract class MultiItemTypeSupport<T> {

    public abstract int getItemViewType(int position, T bean);

    public abstract @LayoutRes
    int getItemLayoutId(int type);

//    public abstract void bindView(BaseViewHolder viewHolder, List<T> list, int position);
}

然后还需要一个ViewHolder的基类

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.support.v4.util.SparseArrayCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * Created by Song on 2019/7/19 11:26
 * I love you three thousand times.
 */
public class BaseViewHolder extends RecyclerView.ViewHolder {

    private SparseArrayCompat<View> mViews = new SparseArrayCompat<>();
    private Context mContext;

    protected BaseViewHolder(Context context, View itemView) {
        super(itemView);
        mContext = context;
    }


    public static BaseViewHolder getViewHolder(Context context, ViewGroup viewGroup, @LayoutRes int layoutId) {

        View itemView = LayoutInflater.from(context).inflate(layoutId, viewGroup, false);

        return new BaseViewHolder(context, itemView);

    }


    public View getView(@IdRes int idRes) {
        View v = mViews.get(idRes);
        if (v == null) {
            v = itemView.findViewById(idRes);
            mViews.put(idRes, v);
        }
        return v;
    }

    public BaseViewHolder setTextOfTextView(@IdRes int idRes, CharSequence text) {
        if (getView(idRes) instanceof TextView) {
            ((TextView) getView(idRes)).setText(text);
        }
        return this;
    }

    public BaseViewHolder setBackgroundOfView(@IdRes int idRes, @DrawableRes int drawableRes) {
        getView(idRes).setBackgroundResource(drawableRes);
        return this;
    }

    public BaseViewHolder setColorOfTextView(@IdRes int idRes, @ColorInt int color) {
        if (getView(idRes) instanceof TextView) {
            ((TextView) getView(idRes)).setTextColor(color);
        }
        return this;
    }

    public BaseViewHolder setImageOfImageView(@IdRes int idRes, @DrawableRes int drawableRes) {
        if (getView(idRes) instanceof ImageView) {
            ((ImageView) getView(idRes)).setImageResource(drawableRes);
        }
        return this;
    }

    public BaseViewHolder setImageOfImageView(@IdRes int idRes, Drawable drawable) {
        if (getView(idRes) instanceof ImageView) {
            ((ImageView) getView(idRes)).setImageDrawable(drawable);
        }
        return this;
    }

    public BaseViewHolder setItemListener(View.OnClickListener listener) {
        itemView.setOnClickListener(listener);
        return this;
    }
}

这时候创建适配器

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Song on 2019/7/19 10:47
 * I love you three thousand times.
 */
public abstract class BaseRecyclerViewOfMultiTypeAdapter<T> extends RecyclerView.Adapter<BaseViewHolder> {

    private MultiItemTypeSupport<T> itemTypeSupport;
    private List<T> mDataList;
    protected Context mContext;
    protected int itemType;

    public BaseRecyclerViewOfMultiTypeAdapter(Context context, MultiItemTypeSupport<T> multiItemTypeSupport, List<T> datas) {
        mContext = context;
        if (datas == null) {
            mDataList = new ArrayList<>();
        } else {
            mDataList = datas;
        }
        itemTypeSupport = multiItemTypeSupport;
    }

    @Override
    public int getItemViewType(int position) {//多类型要重写
        itemType = itemTypeSupport.getItemViewType(position, mDataList.get(position));

        if (itemType == -1) {
            throw new RuntimeException("检查resType字段的值");
        }

        return itemType;
    }

    @Override
    public void onBindViewHolder(BaseViewHolder viewHolder, int i) {
        bindViewHolder(viewHolder, mDataList.get(i));
    }

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        return BaseViewHolder.getViewHolder(this.mContext, viewGroup, itemTypeSupport.getItemLayoutId(i));
    }

    @Override
    public long getItemId(int position) {
        return super.getItemId(position);
    }

    @Override
    public int getItemCount() {
        return mDataList.size();
    }

    public void setDataList(List<T> dataList) {
        if (mDataList == dataList) {
            notifyDataSetChanged();
            return;
        }
        if (dataList != null) {
            mDataList.clear();
            mDataList.addAll(dataList);
            notifyDataSetChanged();
        }
    }

    public void addDataList(List<T> dataList) {
        if (dataList == null) return;
        mDataList.addAll(dataList);
        notifyDataSetChanged();

    }

    public void addDataBean(T dataBean) {
        if (dataBean == null) return;
        mDataList.add(dataBean);
        notifyDataSetChanged();

    }

    public List<T> getDataList() {
        return mDataList;
    }

    public abstract void bindViewHolder(BaseViewHolder holder, T itemBean);
}

  • 要注意上面所有的BaseViewHolder 都要是创建的那个ViewHolder类,不能是RecyclerView.ViewHolder
  • 还有上面辅助类的T 和 适配器类的T 都是同样的数据集的类型

使用方法
先创建多布局的辅助类

public static final int ITEM_ONLY_TEXT = 1;//仅仅是文字的类型
public static final int ITEM_ONE_BIG_PICTURE = 2;//一张大图的类型
public static final int ITEM_ONE_SMALL_PICTURE = 3;//一张小图的类型
public static final int ITEM_THREE_SMALL_PICTURE = 4;//三张小图的类型

private MultiItemTypeSupport<ZhimaListBeanNew.ReportInfo> itemTypeSupport = new MultiItemTypeSupport<ZhimaListBeanNew.ReportInfo>() {
        @Override
        public int getItemViewType(int position, ZhimaListBeanNew.ReportInfo bean) {

            //列表缩略图类型 0 一张小图、1 一张大图、2 三张小图 3纯文字
            switch (bean.imgType) {
                case "3":
                    return ITEM_ONLY_TEXT;
                case "1":
                    return ITEM_ONE_BIG_PICTURE;
                case "0":
                    return ITEM_ONE_SMALL_PICTURE;
                case "2":
                    return ITEM_THREE_SMALL_PICTURE;
            }
            return -1;
        }

        @Override
        public int getItemLayoutId(int type) {

            if (type == -1) {
                //这里直接抛出了运行异常 所以说这个 imgType 一定要是上面的几种类型中的一个 如果没有的话会崩溃 是否崩溃和后台返回数据有关
                //可以处理这个异常 返回个默认的布局就好 亦或者返回个空布局只是相关的数据就没有用了(展示不出来)
                throw new RuntimeException("请检查ItemViewType");
            }

            switch (type) {
                case ITEM_ONLY_TEXT:
                    return R.layout.item_zhima_list_only_text;//相应的布局文件
                case ITEM_ONE_BIG_PICTURE:
                    return R.layout.item_zhima_list_one_big_picture;
                case ITEM_ONE_SMALL_PICTURE:
                    return R.layout.item_zhima_list_one_small_picture;
                case ITEM_THREE_SMALL_PICTURE:
                    return R.layout.item_zhima_list_three_small_picture;
            }
            return -1;
        }
    };

然后初始化适配器

if (multiTypeAdapter == null) {
            multiTypeAdapter = new BaseRecyclerViewOfMultiTypeAdapter<ZhimaListBeanNew.ReportInfo>(this, itemTypeSupport, null) {

                @Override
                public void bindViewHolder(final BaseViewHolder holder, final ZhimaListBeanNew.ReportInfo itemBean) {

                    holder.setItemListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {

                            clickPosition = holder.getAdapterPosition();

                            //跳详情页面
                            Intent intent = new Intent(ActivityZhimaIndex.this, ActivityZhimaContent.class);
                            intent.putExtra("id", itemBean.id);
                            startActivity(intent);
                        }
                    });
                    int heightTitle = (int) (getResources().getDimension(R.dimen.dm032) - getResources().getDimension(R.dimen.dm002));
                    ((TextView) holder.getView(R.id.tv_item_zhima_title)).setText(TextViewHelper.setLeftImage(ActivityZhimaIndex.this, R.drawable.iv_zhima_list_title, itemBean.title, heightTitle));

                    holder.setTextOfTextView(R.id.tv_item_zhima_content, itemBean.desc);

                    //需要付费并且订阅人数不为空
                    if ("1".equals(itemBean.needPay) && !TextUtils.isEmpty(itemBean.buyCount)) {
                        holder.setTextOfTextView(R.id.tv_item_zhima_left_text, itemBean.buyCount + " " + itemBean.time + " " + itemBean.ubName);

                        //已订阅
                        if ("1".equals(itemBean.hasBuy)) {
                            holder.setTextOfTextView(R.id.tv_item_zhima_right_text, "已购买")
                                    .setColorOfTextView(R.id.tv_item_zhima_right_text, getResources().getColor(R.color.color69, null));
                            holder.getView(R.id.tv_item_zhima_right_text).setVisibility(View.VISIBLE);
                            Glide.with(ActivityZhimaIndex.this).load(R.drawable.iv_zhima_not_suo).into((ImageView) (holder.getView(R.id.iv_item_zhima_suo)));
                            holder.getView(R.id.iv_item_zhima_suo).setVisibility(View.VISIBLE);
                        } else {
                            holder.setTextOfTextView(R.id.tv_item_zhima_right_text, "解锁全文")
                                    .setColorOfTextView(R.id.tv_item_zhima_right_text, CommonUtils.getColorAccent(ActivityZhimaIndex.this));
                            holder.getView(R.id.tv_item_zhima_right_text).setVisibility(View.VISIBLE);
                            Glide.with(ActivityZhimaIndex.this).load(R.drawable.iv_zhima_suo).into((ImageView) (holder.getView(R.id.iv_item_zhima_suo)));
                            holder.getView(R.id.iv_item_zhima_suo).setVisibility(View.VISIBLE);
                        }
                    } else {
                        holder.setTextOfTextView(R.id.tv_item_zhima_left_text, itemBean.time + " " + itemBean.ubName);
                        holder.getView(R.id.iv_item_zhima_suo).setVisibility(View.GONE);
                        holder.getView(R.id.tv_item_zhima_right_text).setVisibility(View.GONE);
                    }
                    //上面的是不同布局但是有相同部分的数据绑定
                    //下面就是不同布局各自的数据绑定
                    switch (itemType) {
                        case ITEM_ONLY_TEXT:
                            return;
                        case ITEM_ONE_BIG_PICTURE:
                            Glide.with(ActivityZhimaIndex.this).load(itemBean.img1)
                                    .into((ImageView) holder.getView(R.id.iv_item_zhima_big_one));
                            return;
                        case ITEM_ONE_SMALL_PICTURE:
                            Glide.with(ActivityZhimaIndex.this).load(itemBean.img1)
                                    .into((ImageView) holder.getView(R.id.iv_item_zhima_small_first));
                            return;
                        case ITEM_THREE_SMALL_PICTURE:
                            Glide.with(ActivityZhimaIndex.this).load(itemBean.img1)
                                    .into((ImageView) holder.getView(R.id.iv_item_zhima_small_first));
                            Glide.with(ActivityZhimaIndex.this).load(itemBean.img2)
                                    .into((ImageView) holder.getView(R.id.iv_item_zhima_small_second));
                            Glide.with(ActivityZhimaIndex.this).load(itemBean.img3)
                                    .into((ImageView) holder.getView(R.id.iv_item_zhima_small_third));
                            return;
                    }

                }

            //!!!看这里 这里可能会重写适配器中的其他方法
            };
        }
  • 在我使用的时候,因为有item复用的问题,要用到onViewRecycled 来解绑Tag,但是在重写的时候一定要注意下面代码
               @Override
                public void onViewRecycled(@NonNull XXX holder) {
                    super.onViewRecycled(holder);
                }
  • 上面的XXX 一定要是你自己写的那个ViewHolder 类,不然会报 Method does not override method from its superclass 重写错误

  • 还有在处理复用问题的时候最好使用SparseArrayCompat<View> 不要使用Map<Object,View>


之后将数据绑定的抽象方法放到辅助类里面,然后在适配器中的构造函数的参数中直接new 一个辅助类就行了,不用单独在创建辅助类对象了

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,640评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,254评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,011评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,755评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,774评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,610评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,352评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,257评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,717评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,894评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,021评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,735评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,354评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,936评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,054评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,224评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,974评论 2 355

推荐阅读更多精彩内容