封装RecyclerView的基础适配器BaseAdapter

来源:互联网 发布:乎是不是多音字 编辑:程序博客网 时间:2024/06/08 11:04

前言: 项目中我们经常使用RecylcerView,所以写Adapter也是必不可少的,建立一个BaseAdapter,封装公共部分,不仅可以减少代码量,也便于管理。

分析: 各列表的不同之处:1,填充数据的数据类型;2,item布局;3,item绑定数据的操作;4,ViewHolder中item的子view数量和种类;基本上就这四种不同之处了,我们针对这四点进行处理。

封装: 我封装的适配器,包括了对无数据和无网络情况处理,首先看一下封装好的基础适配器。
BaseRecycleViewAdapter.java

public abstract class RecyclerViewBaseAdapter<T> extends RecyclerView.Adapter<RecyclerViewBaseAdapter.BaseViewHolder> {    protected List<T> mDatas;                           //数据源    private final int NO_NETWORK = 101, NO_DATA = 102;  //无网络,无数据    public RecyclerViewBaseAdapter(List<T> mDatas) {        this.mDatas = mDatas;    }    @Override    public int getItemCount() {        return mDatas.size() > 0 ? mDatas.size() : 1;    }    @Override    public int getItemViewType(int position) {        if (!NetUtil.isNetworkAvailable()) {            return NO_NETWORK;        }        if (mDatas.size() <= 0) {            return NO_DATA;        }        return super.getItemViewType(position);    }    @Override    public RecyclerViewBaseAdapter.BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = null;        switch (viewType) {            case NO_NETWORK:                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_no_network, parent, false);                break;            case NO_DATA:                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_no_data, parent, false);                break;            default:                view = LayoutInflater.from(parent.getContext()).inflate(getLayoutId(), parent, false);                break;        }        return new BaseViewHolder(view);    }    @Override    public void onBindViewHolder(RecyclerViewBaseAdapter.BaseViewHolder holder, int position) {        if (mDatas.size()<=0 || getItemViewType(position)==NO_NETWORK) {            /*这里可以做无网络或者无数据时点击处理处理,例如写一个新接口,把事件处理传递给activity去做*/            return;        }        bindData(holder, position);    }    /**     * 给ImageView设置值     */    protected void setImageViewValue(View view, int resId) {        if (view instanceof ImageView) {            ((ImageView) view).setImageResource(resId);        }    }    protected void setImageViewValue(View view, String imgUrl) {        if (view instanceof ImageView) {            //使用Glide或是Picasso加载网络图片        }    }    /**     * 给textview设置值     */    protected void setTextViewValue(View view, String text) {        if (view instanceof TextView) {            ((TextView) view).setText(text);        } else if (view instanceof Button) {            ((Button) view).setText(text);        }    }    /**     * 给Item绑定数据     */    protected abstract void bindData(BaseViewHolder holder, int position);    /**     * 获取item布局     */    protected abstract int getLayoutId();    public class BaseViewHolder extends RecyclerView.ViewHolder {        private Map<Integer, View> mViewMap;   //保存item的view集合        public BaseViewHolder(View itemView) {            super(itemView);            mViewMap = new HashMap<>();        }        /**         * 获取item中的某个view         */        public View getView(int id) {            View view = mViewMap.get(id);            if (view == null) {                view = itemView.findViewById(id);                mViewMap.put(id, view);            }            return view;        }    }    protected OnItemClickListener onItemClickListener;  //条目的点击事件处理    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {        this.onItemClickListener = onItemClickListener;    }    public interface OnItemClickListener{        void onClick(View view, int position);    }}

讲解: 首先,不同点1,我们使用泛型RecyclerViewBaseAdapter< T >来做处理,在实现基础适配器时,首先会指定数据类型,例如:

public class HotFgListStrAdapter extends RecyclerViewBaseAdapter<String> {}

;其次,不同点2和不同点3,我们都写了抽象方法交给子适配器去做;最后,不同点4,也是主要处理的一点,因为不同item的子view个数和类型可能都不同,所以我们在ViewHolder中建立一个Map,子view的id组为键,子view的类型作为值,每次通过子view的id去map获取,如果有,则取出来,没有则通过findViewById来得到,然后存到Map中, 这样以来也达到了复用子view的效果。

使用: 写一个子适配器来实现基础适配器
HotFgListStrAdapter.java

public class HotFgListStrAdapter extends RecyclerViewBaseAdapter<String> {    public HotFgListStrAdapter(List<String> mDatas) {        super(mDatas);    }    @Override    protected void bindData(final BaseViewHolder holder, int position) {        setTextViewValue(holder.getView(R.id.tv_title), mDatas.get(position));        holder.itemView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                onItemClickListener.onClick(view, holder.getLayoutPosition());            }        });    }    @Override    protected int getLayoutId() {        return R.layout.item_recyclerview;    }}

看上面的子适配器,代码相当简洁。因为这个例子实在上篇博客 的基础上封装的,所以demo的运行效果可以看一下上一片博客,demo的代码可以在文章最后进行下载。

代码下载

1 0
原创粉丝点击