美文网首页
通用RecyclerView.Adapter

通用RecyclerView.Adapter

作者: shuixingge | 来源:发表于2016-12-18 17:43 被阅读110次

    参考_鸿洋

    一:背景

    在最开始学习Android的时候,大部人用ListView都会用到ViewHolder,而对于RecyclerView则是强制使用ViewHolder的,但是很多新手(包括我)一开始都会一个RecyclerView使用一个ViewHolder,这样就会导致ViewHolder复用性太差,而且如果当item布局改变时,ViewHolder也会需要去调整,这对于大型的开发项目显然是十分不利的,所以有必要去封装一个通用的ViewHolder。
    比如像如下的代码,当在item布局中去添加一个新的TextView时,就需要去手动的添加。

    public static class ViewHolder extends RecyclerView.ViewHolder {
    
            @Bind(R.id.recipe_image)
            ImageView image;
            @Bind(R.id.recipe_tag)
            TextView tag;
            @Bind(R.id.recipe_name)
            TextView name;
            @Bind(R.id.recipe_food)
            TextView food;
    
            public ViewHolder(View itemView) {
                super(itemView);
                ButterKnife.bind(this, itemView);
            }
    }
    

    二:封装ViewHolder

    在RecyclerView中ViewHolder是作为泛型传入的,因为是通用的ViewHolder,所以ViewHolder的内部的控件不能写死,在此我们采用SparseArray来缓存布局中的Views,当getView时,如果SparseArray存储了View的实例,那么直接从SparseArray获取,如果没有存储,那么从itemView上findViewById来查找。除此之外还提供了根据itemView的id获取ViewHolder方法getViewHolder()。

    即BaseViewHolder的代码如下

    public class ViewHolder extends RecyclerView.ViewHolder
    {
        private SparseArray<View> mViews;
        private View mConvertView;
        private Context mContext;
       //1 ViewHolder的构造方法
        public ViewHolder(Context context, View itemView, ViewGroup parent)
        {
            super(itemView);
            mContext = context;
            mConvertView = itemView;
            mViews = new SparseArray<View>();
        }
    
      //2 通过item_layout的id来构造ViewHolder
        public static ViewHolder get(Context context, ViewGroup parent, int layoutId)
        {
    
            View itemView = LayoutInflater.from(context).inflate(layoutId, parent,
                    false);
            ViewHolder holder = new ViewHolder(context, itemView, parent, position);
            return holder;
        }
    
      
      // 从缓存中获取View控件
        public <T extends View> T getView(int viewId)
        {
            View view = mViews.get(viewId);
            if (view == null)
            {
                view = mConvertView.findViewById(viewId);
                mViews.put(viewId, view);
            }
            return (T) view;
        }
    }
    

    三: 通用RecyclerView.Adapter

    前面已经封装好了通用的ViewHolder,RecyclerView.Adapter的两个主要方法是onCreateViewHolder()和onBindViewHolder(),onCreateViewHolder可以根据ViewHolder.getViewHplder生成ViewHolder,onBindViewHolder()主要用来绑定事件和数据,抽象出一个convert方法来完成事件的绑定。

    public abstract class CommonAdapter<T> extends RecyclerView.Adapter<ViewHolder>
    {
        protected Context mContext;
        protected int mLayoutId;
        protected List<T> mDatas;
        protected LayoutInflater mInflater;
    
    
        public CommonAdapter(Context context, int layoutId, List<T> datas)
        {
            mContext = context;
            mInflater = LayoutInflater.from(context);
            mLayoutId = layoutId;
            mDatas = datas;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType)
        {
            ViewHolder viewHolder = ViewHolder.get(mContext, parent, mLayoutId);
            return viewHolder;
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position)
        {
            holder.updatePosition(position);
            convert(holder, mDatas.get(position));
        }
    
        public abstract void convert(ViewHolder holder, T t);
    
        @Override
        public int getItemCount()
        {
            return mDatas.size();
        }
    }
    

    使用:实现convert方法,并在convert方法中完成事件的绑定即可。
    如果这个时候,如果要在item布局中去添加一个新的TextView时,只需要在绑定的时候去绑定就可以,而不需要像未封装时去修改ViewHolder代码,然后再去绑定

    mRecyclerView.setAdapter(new CommonAdapter<String>(this, R.layout.item_list, mDatas)
    {
        @Override
        public void convert(ViewHolder holder, String s)
        {
            TextView tv = holder.getView(R.id.id_item_list_title);
            tv.setText(s);
        }
    });
    

    相关文章

      网友评论

          本文标题:通用RecyclerView.Adapter

          本文链接:https://www.haomeiwen.com/subject/copomttx.html