美文网首页
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