美文网首页
RecyclerView没有HeaderView咋办——再回忆

RecyclerView没有HeaderView咋办——再回忆

作者: 生活简单些 | 来源:发表于2019-03-16 20:10 被阅读0次

      这是一个老生常谈的问题,现在网上搜搜已经到处是答案,但是RecyclerView刚出来的时候可是让很多人苦恼过,甚至有人想把ListView中的HeaderView和FooterView硬搬过来,而且还要考虑列表中真实数据错位问题,很麻烦。
      其实是完全没有必要的,列表加headerView是小事,中间穿插多个不一样的view才是重点,尤其像头条新闻这类应用,列表中会穿插各种形状各异的栏目,还有比较典型的是聊天应用(微信),聊天列表中有各种UI呈现形式(图片,文字,视频,音乐,表情,地图等等)。
      其实Android已经提供给我们办法了,而且是一个非常解耦的办法:通过自定义的viewType来区别对待创建viewHolder和给viewHolder绑定数据。

    /**
     * 所有viewHolder数据类的基类
     */
    public class ViewTypeData {
        public interface ViewType {
            int HEAD = 10000;
            int FOOT = 10001;
            int DEFAULT = 0;
        }
    
        public int viewType = ViewType.DEFAULT;
    
        public ViewTypeData (int viewType){
            this.viewType = viewType;
        }
    }
    
    public class ViewTypeDataA extends ViewTypeData {
        public static final int VIEW_TYPE = 1;
    
        public String name;
        public int age;
        public int height;
    
        public ViewTypeDataA(){
            super(VIEW_TYPE);
        }
    }
    
    public class ViewTypeDataB extends ViewTypeData {
        public static final int VIEW_TYPE = 2;
    
        public String pic;
        public int title;
        public int subTitle;
    
        public ViewTypeDataB(){
            super(VIEW_TYPE);
        }
    }
    
    public class ViewTypeDataC extends ViewTypeData {
        public static final int VIEW_TYPE = 3;
    
        public String city;
        public int district;
        public int address;
    
        public ViewTypeDataC(){
            super(VIEW_TYPE);
        }
    }
    

    这里我们约定所有要呈现在RecyclerView中的数据类(json类)在定义时都继承ViewTypeData并在其构造方法里赋值告知对应的viewType值。

    public class RecyclerViewAdapter extends RecyclerView.Adapter{
        private List<ViewTypeData> mDataList = new ArrayList<>();
    
        public void setData(List<ViewTypeData> dataList){
            mDataList = dataList;
            notifyDataSetChanged();
        }
    
        @Override
        public RecyclerView.ViewHolder onCreateiewHolder(@NonNull ViewGroup parent, int viewType) {
            switch(viewType){
                if (viewType == ViewTypeDataA.VIEW_TYPE) {
                    return new ViewHolderA(inflater.inflate(R.layout.view_type_a, parent, false));
                } else if (viewType == ViewTypeDataB.VIEW_TYPE) {
                    return new ViewHolderB(inflater.inflate(R.layout.view_type_b, parent, false));
                } else if (viewType == ViewTypeDataC.VIEW_TYPE) {
                    return new ViewHolderC(inflater.inflate(R.layout.view_type_c, parent, false));
                }
    
                // 有多少种item的呈现形式就有多少种viewType
            }
        }
    
        @Override
        protected void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
            ViewTypeData data = mDataList.get(position);
            if (holder instanceof ViewHolderA){
                ViewHolderA viewHolder = (ViewHolderA)holder;
                viewHolder.setData((ViewTypeAData)data);
            } else if (viewType instanceof ViewHolderB){
                ViewHolderB viewHolder = (ViewHolderB)holder;
                viewHolder.setData((ViewTypeBData)data);
            } else if (viewType instanceof ViewHolderC){
                ViewHolderC viewHolder = (ViewHolderC)holder;
                viewHolder.setData((ViewTypeCData)data);
            }
    
            // 有多少种item的呈现形式就有多少种viewHolder赋值
        }
    
        @Override
        public int getItemCount() {
            return mDataList.size();
        }
    }
    
    // 模拟不同形式的列表数据插入
    List<ViewTypeData> dataList = new ArrayList<>();
    dataList.addAll(viewTypeDataAList);
    dataList.addAll(viewTypeDataBList);
    dataList.addAll(viewTypeDataCList);
    recycleViewAdapter.setData(dataList);
    

    由上可见列表中不同的item展示是根据viewType一一判断生成的,但为什么说这是一种解耦的思路呢?

      在具体项目中,列表中的数据来源可能来自多个接口,也有可能是特定的逻辑本地生成然后插入的,最重要的列表中item显示的顺序如何保证。从解耦角度考虑,这跟传入到RecyclerViewAdapter里的dataList数据有直接关系,这里的dataList某种意义上讲就是一个先进先出的队列,数据在dataList是什么顺序在列表中呈现就是什么顺序。因此工作的重心是如何组织dataList里的数据以及顺序,而不是在adapter里牵扯各种业务逻辑,毕竟adapter内部也有它烦人的工作要做,如:UI的渲染,事件的监听等,只希望它们之间的工作没有强关联。
      我想现在要在RecyclerView里加个headerView不麻烦了吧。

    相关文章

      网友评论

          本文标题:RecyclerView没有HeaderView咋办——再回忆

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