Android 万能的强大的RecyclerView适配器Adapter

作者 : 开心源码 本文共9540个字,预计阅读时间需要24分钟 发布时间: 2022-05-12 共172人阅读

开篇

??相信大家在项目的开发中都用到了QuickAdapter,也感觉到了它的确提升了少量我们的开发效率。不仅仅你用了,我也用了,但是我还是觉得它还有很大的提升空间。为此,我特意抽时间封装了此RecyclerView适配器。

效果截屏

PullToRefreshRecyclerView

立即体验

扫描以下二维码下载体验App(体验App内嵌版本升级检测功能):

扫描下载体验App

传送门: JustinRoom/SimpleAdapterDemo

gradle引用

    implementation 'jsc.kit.adapter:adapter-component:_latestVersion'

简析源码

public abstract class BaseHeaderFooterAdapter<H, D, F, E, VH extends BaseHeaderFooterAdapter.BaseViewHolder> extends RecyclerView.Adapter<VH> {}

1、封装了4中ViewType类型:H——头(header)、D——数据(data)、F——尾(footer)、E——空列表(empty)

    /**     * header 视图     */    public static final int TYPE_HEADER = 1000;    /**     * data 数据视图     */    public static final int TYPE_DATA = 1001;    /**     * footer 视图     */    public static final int TYPE_FOOTER = 1002;    /**     * 空列表视图     */    public static final int TYPE_EMPTY = 1003;    private List<H> headers = new ArrayList<>();    private List<D> data = new ArrayList<>();    private List<F> footers = new ArrayList<>();    private List<E> empties = new ArrayList<>();

2、获取position位置的ViewType

    @Override    public int getItemCount() {        return getHeaderSize() + getInternalSize() + getFooterSize();    }    @ViewType    @Override    public int getItemViewType(int position) {        if (position >= getHeaderSize() + getInternalSize() + getFooterSize())            return UNKNOWN;        if (position >= getHeaderSize() + getInternalSize())            return TYPE_FOOTER;        if (position >= getHeaderSize())            return isEmptyData() ? TYPE_EMPTY : TYPE_DATA;        if (position >= 0)            return TYPE_HEADER;        return UNKNOWN;    }    private int getInternalSize() {        return isEmptyData() ? getEmptySize() : getDataSize();    }

3、封装BaseViewHolder,增加少量常用方法。
public static class BaseViewHolder extends RecyclerView.ViewHolder {}

常用方法:
public <V extends View> V findViewById(@IdRes int id)
public void setText(@IdRes int id, CharSequence txt)
public void setTextColor(@IdRes int id, @ColorInt int color)
public void setTextSize(@IdRes int id, float size)
public void setTextSize(@IdRes int id, int unit, float size)
public void setVisibility(@IdRes int id, int visibility)
public void setSelected(@IdRes int id, boolean selected)
public void setEnabled(@IdRes int id, boolean enable)
public void setBackgroundColor(@IdRes int id, @ColorInt int color)
public void setBackgroundResource(@IdRes int id, @DrawableRes int resId)
public void setBackground(@IdRes int id, Drawable background)
public void setTag(@IdRes int id, final Object tag)
public void setTag(@IdRes int id, int key, final Object tag)
void setPositionTag(int position)
void addOnItemClickListener(View.OnClickListener listener)
void addOnItemLongClickListener(View.OnLongClickListener listener)
void addOnChildClickListener(@IdRes int id, View.OnClickListener listener)
void addOnChildLongClickListener(@IdRes int id, View.OnLongClickListener listener)

4、绑定View

    @CallSuper    @Override    public void onBindViewHolder(@NonNull VH holder, int position) {        holder.setPositionTag(position);        holder.addOnItemClickListener(onItemClickListener == null ? null : getDefaultItemClickListener());        holder.addOnItemLongClickListener(onItemLongClickListener == null ? null : getDefaultItemLongClickListener());        switch (getItemViewType(position)) {            case TYPE_HEADER:                onBindHeaderViewHolder(holder, position, getHeaderAt(position));                break;            case TYPE_DATA:                onBindDataViewHolder(holder, position, getDataAt(position));                break;            case TYPE_FOOTER:                onBindFooterViewHolder(holder, position, getFooterAt(position));                break;            case TYPE_EMPTY:                onBindEmptyViewHolder(holder, position, getEmptyAt(position));                break;            case UNKNOWN:                break;        }    }

5、根据不同的ViewType创立不同View视图:SimpleAdapter

public class SimpleAdapter<H, D, F, E> extends BaseHeaderFooterAdapter<H, D, F, E, BaseHeaderFooterAdapter.BaseViewHolder> {    public SimpleAdapter() {    }    public SimpleAdapter(@LayoutRes int dataLayoutId) {        super(dataLayoutId);    }    @NonNull    @Override    public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {        switch (viewType) {            case TYPE_HEADER:                if (getHeaderLayoutId() == -1)                    throw new IllegalArgumentException(getClass().getSimpleName() + " : please set header layout first.");                return new BaseViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(getHeaderLayoutId(), viewGroup, false));            case TYPE_DATA:                if (getDataLayoutId() == -1)                    throw new IllegalArgumentException(getClass().getSimpleName() + " : please set footer layout first.");                return new BaseViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(getDataLayoutId(), viewGroup, false));            case TYPE_FOOTER:                if (getFooterLayoutId() == -1)                    throw new IllegalArgumentException(getClass().getSimpleName() + " : please set footer layout first.");                return new BaseViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(getFooterLayoutId(), viewGroup, false));            case TYPE_EMPTY:                return new BaseViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(getEmptyLayoutId() == -1 ? R.layout.recycler_default_empty_list_layout : getEmptyLayoutId(), viewGroup, false));            default:                TextView textView = new TextView(viewGroup.getContext());                textView.setTextColor(Color.RED);                textView.setGravity(Gravity.CENTER);                textView.setText("Unknown view type");                textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));                return new BaseViewHolder(textView);        }    }}

使用示例

  • 1、简单使用示例:
        RecyclerView recyclerView;        adapter2 = new SimpleAdapter2<MaterielOrderDetail, MaterielDetail, Object>() {            @Override            protected void onBindHeaderViewHolder(@NonNull BaseViewHolder holder, int position, MaterielOrderDetail headerBean) {                holder.setText(R.id.tv_company_name, formatValue("公司名称:", headerBean.getOrgName()));                holder.setText(R.id.tv_type, formatValue("\u3000类型:", headerBean.getEventTypeName()));                holder.setText(R.id.tv_warehouse_name, formatValue("仓库名称:", headerBean.getWarehouseName()));                holder.setText(R.id.tv_partner_name, formatValue("供应商:", headerBean.getPartnerName()));                if (headerBean.getCreateTime() > 0) {                    holder.setText(R.id.tv_create_time, formatValue("创立时间:", format.format(new Date(headerBean.getCreateTime()))));                } else {                    holder.setText(R.id.tv_create_time, "");                }                holder.setText(R.id.tv_creator, formatValue("创立人:", headerBean.getCreatePersonName()));                //已经审核通过                if (MaterielMenu.orderStatus.get(2).getKey().equals(headerBean.getStatus())) {                    holder.setText(R.id.tv_auditing_time, formatValue("审核时间:", format.format(new Date(headerBean.getApproveTime()))));                    holder.setText(R.id.tv_auditor, formatValue("审核人:", headerBean.getApprovePersonName()));                } else {                    holder.setText(R.id.tv_auditing_time, formatValue("审核时间:", "--"));                    holder.setText(R.id.tv_auditor, formatValue("审核人:", "--"));                }                holder.setText(R.id.tv_storage_type_label, String.format(Locale.CHINA, "%s物料:", opAction1 == IMateriel.OP_ACTION_IN ? "入库" : "出库"));            }            @Override            protected void onBindDataViewHolder(@NonNull BaseViewHolder holder, int position, MaterielDetail dataBean) {                holder.setText(R.id.tv_materiel_name, dataBean.getMaterialName());                if (dataBean.getBatchManage()) {                    holder.setText(R.id.tv_materiel_batch, String.format(Locale.CHINA, "(%s)", dataBean.getBatch()));                } else {                    holder.setText(R.id.tv_materiel_batch, "");                }                holder.setVisibility(R.id.btn_materiel_delete, View.GONE);                holder.setText(R.id.tv_business_unit, formatValue("业务单位:", dataBean.getMultiUnitName()));                holder.setText(R.id.tv_business_number, formatValue("业务数量:", String.valueOf(dataBean.getQuantity())));                holder.setText(R.id.tv_accounting_unit, formatValue("核算单位:", dataBean.getAccountUnitName()));                holder.setText(R.id.tv_accounting_number, formatValue("核算数量:", String.valueOf(dataBean.getAccountQuantity())));            }            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd\u2000HH:mm", Locale.CHINA);            CharSequence formatValue(String label, String value) {                if (value == null || value.trim().length() == 0) {                    return label;                }                SpannableString spannableString = new SpannableString(label + value);                spannableString.setSpan(new ForegroundColorSpan(0xFF90FFBE), label.length(), label.length() + value.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);                return spannableString;            }        };        adapter2.setHeaderLayoutId(R.layout.breed_fragment_materiel_detail_header);        adapter2.setDataLayoutId(R.layout.breed_list_item_materiel);        adapter2.bindRecyclerView(recyclerView);        adapter2.addHeader(new MaterielOrderDetail());
  • 2、各种事件监听:

2.1、itemView的点击事件监听:

public interface OnItemClickListener<H, D, F, E> {    //每一条header的点击监听    void onHeaderItemClick(@NonNull View headerItemView, int position, H headerBean);    //每一条data的点击监听    void onDataItemClick(@NonNull View dataItemView, int position, D dataBean);    //每一条footer的点击监听    void onFooterItemClick(@NonNull View footerItemView, int position, F footerBean);    //每一条empty的点击监听    void onEmptyItemClick(@NonNull View emptyItemView, int position, E emptyBean);}

2.2、itemViewchild view的点击事件监听

public interface OnItemChildClickListener<H, D, F, E> {    //header child view点击监听    void onHeaderItemChildClick(@NonNull View headerChild, int position, H headerBean);    //data child view点击监听    void onDataItemChildClick(@NonNull View dataItemChild, int position, D dataBean);    //footer child view点击监听    void onFooterItemChildClick(@NonNull View footerChild, int position, F footerBean);    //empty child view点击监听    void onEmptyItemChildClick(@NonNull View emptyChild, int position, E emptyBean);}

2.3、itemView的长按事件监听:

public interface OnItemLongClickListener<H, D, F, E> {    //每一条header的长按监听    boolean onHeaderItemLongClick(@NonNull View headerItemView, int position, H headerBean);    //每一条data的长按监听    boolean onDataItemLongClick(@NonNull View dataItemView, int position, D dataBean);    //每一条footer的长按监听    boolean onFooterItemLongClick(@NonNull View footerItemView, int position, F footerBean);    //每一条empty的长按监听    boolean onEmptyItemLongClick(@NonNull View emptyItemView, int position, E emptyBean);}

2.4、itemViewchild view的长按事件监听

public interface OnItemChildLongClickListener<H, D, F, E> {    //header child view长按监听    boolean onHeaderItemChildLongClick(@NonNull View headerChild, int position, H headerBean);    //data child view长按监听    boolean onDataItemChildLongClick(@NonNull View dataItemChild, int position, D dataBean);    //footer child view长按监听    boolean onFooterItemChildLongClick(@NonNull View footerChild, int position, F footerBean);    //empty child view长按监听    boolean onEmptyItemChildLongClick(@NonNull View emptyChild, int position, E emptyBean);}

使用详情就到这里。
假如你觉得还不错的话,在GitHub上给一颗星星?支持下吧。谢谢!假如在使用过程中不懂(或者需要改进的地方),可以在评论里给我留言,也可以联络我。
微信:eoy9527QQ:1006368252

篇尾

一个人最怕不老实,青年人最可贵的是老实作风。”老实”就是不自欺欺人,做到不欺骗人家容易,不欺骗自己最难。”老实作风”就是脚踏实地,不占便宜。世界上没有便宜的事,谁想占便宜水就会吃亏。 —— 徐特立

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Android 万能的强大的RecyclerView适配器Adapter

发表回复