安卓项目实战之:4步实现用一个recyclerview实现列表嵌套效果,完美替代RecycleView嵌套方案

前言

在这里插入图片描述
对于项目中要实现如上图所示的界面效果,可能有的人会想到使用RecycleView嵌套的方式去解决,虽然这种方式可以实现,但是嵌套带来的问题还是比较麻烦的,比如滑动冲突什么的,今天我们就介绍一种优雅的方式,只需要一个RecycleView就可以实现这样的效果,基本思路如下:

我们发现上图中的布局样式其实只有两种,我们将上图中的区域1划分为一个类型(String),区域2划分为一个类型(自定义实体类(OpenRecordBean))。将这两种类型的所有数据依次放入到一个List集合中,存放完之后,根据上面的需求,这个集合里面的结构应该是这样的:【String,OpenRecordBean,String,OpenRecordBean,OpenRecordBean,String,OpenRecordBean,OpenRecordBean,OpenRecordBean…….】,因为集合里面的元素类型并不单一,所以泛型使用Object,然后在adapter中根据集合List< Object >元素的类型,选择不同的布局去加载即可。

具体实现

该列表数据我们一般会通过一个接口从服务器端去获取,假如最终获取的json格式的数据如下:

{
"code" : 1000,
"data" : [{"dateTitle":"2018-06-14","logDOList":[{"cellId":0,"deviceName":"东大门1","deviceType":0,"fullName":"张三1","ghsUserId":0,"id":0,"openState":0,"openType":1,"roomId":0,"updateTime":"10:22","villageId":0},{"cellId":0,"deviceName":"东大门2","deviceType":0,"fullName":"张三2","ghsUserId":0,"id":0,"openState":0,"openType":2,"roomId":0,"updateTime":"10:22","villageId":0},{"cellId":0,"deviceName":"东大门3","deviceType":0,"fullName":"张三3","ghsUserId":0,"id":0,"openState":0,"openType":3,"roomId":0,"updateTime":"10:22","villageId":0}]},{"dateTitle":"2018-06-10","logDOList":[{"cellId":0,"deviceName":"南大门1","deviceType":0,"fullName":"李四1","ghsUserId":0,"id":0,"openState":0,"openType":1,"roomId":0,"updateTime":"10:22","villageId":0},{"cellId":0,"deviceName":"南大门2","deviceType":0,"fullName":"李四2","ghsUserId":0,"id":0,"openState":0,"openType":2,"roomId":0,"updateTime":"10:22","villageId":0},{"cellId":0,"deviceName":"南大门3","deviceType":0,"fullName":"李四3","ghsUserId":0,"id":0,"openState":0,"openType":3,"roomId":0,"updateTime":"10:22","villageId":0}]}]
"message" : "成功"
}

1,首先我们根据上面的json字符串我们抽象出实体类 OpenRecordBean 如下,可以借助GsonFormat生成:

public class OpenRecordBean {

    private int code;
    private String message;
    private List<DataBean> data;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public List<DataBean> getData() {
        return data;
    }

    public void setData(List<DataBean> data) {
        this.data = data;
    }

    public static class DataBean {
        /**
         * dateTitle : 2018-06-14
         * logDOList : [{"cellId":0,"deviceName":"东大门1","deviceType":0,"fullName":"张三1","ghsUserId":0,"id":0,"openState":0,"openType":1,"roomId":0,"updateTime":"10:22","villageId":0},{"cellId":0,"deviceName":"东大门2","deviceType":0,"fullName":"张三2","ghsUserId":0,"id":0,"openState":0,"openType":2,"roomId":0,"updateTime":"10:22","villageId":0},{"cellId":0,"deviceName":"东大门3","deviceType":0,"fullName":"张三3","ghsUserId":0,"id":0,"openState":0,"openType":3,"roomId":0,"updateTime":"10:22","villageId":0}]
         */

        private String dateTitle;
        private List<LogDOListBean> logDOList;

        public String getDateTitle() {
            return dateTitle;
        }

        public void setDateTitle(String dateTitle) {
            this.dateTitle = dateTitle;
        }

        public List<LogDOListBean> getLogDOList() {
            return logDOList;
        }

        public void setLogDOList(List<LogDOListBean> logDOList) {
            this.logDOList = logDOList;
        }

        public static class LogDOListBean {
            /**
             * cellId : 0
             * deviceName : 东大门1
             * deviceType : 0
             * fullName : 张三1
             * ghsUserId : 0
             * id : 0
             * openState : 0
             * openType : 1
             * roomId : 0
             * updateTime : 10:22
             * villageId : 0
             */

            private int cellId;
            private String deviceName;
            private int deviceType;
            private String fullName;
            private int ghsUserId;
            private int id;
            private int openState;
            private int openType;
            private int roomId;
            private String updateTime;
            private int villageId;

            public int getCellId() {
                return cellId;
            }

            public void setCellId(int cellId) {
                this.cellId = cellId;
            }

            public String getDeviceName() {
                return deviceName;
            }

            public void setDeviceName(String deviceName) {
                this.deviceName = deviceName;
            }

            public int getDeviceType() {
                return deviceType;
            }

            public void setDeviceType(int deviceType) {
                this.deviceType = deviceType;
            }

            public String getFullName() {
                return fullName;
            }

            public void setFullName(String fullName) {
                this.fullName = fullName;
            }

            public int getGhsUserId() {
                return ghsUserId;
            }

            public void setGhsUserId(int ghsUserId) {
                this.ghsUserId = ghsUserId;
            }

            public int getId() {
                return id;
            }

            public void setId(int id) {
                this.id = id;
            }

            public int getOpenState() {
                return openState;
            }

            public void setOpenState(int openState) {
                this.openState = openState;
            }

            public int getOpenType() {
                return openType;
            }

            public void setOpenType(int openType) {
                this.openType = openType;
            }

            public int getRoomId() {
                return roomId;
            }

            public void setRoomId(int roomId) {
                this.roomId = roomId;
            }

            public String getUpdateTime() {
                return updateTime;
            }

            public void setUpdateTime(String updateTime) {
                this.updateTime = updateTime;
            }

            public int getVillageId() {
                return villageId;
            }

            public void setVillageId(int villageId) {
                this.villageId = villageId;
            }
        }
    }
}

2,布局文件很简单就仅仅只是定义一个RecycleView控件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycleView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v7.widget.RecyclerView>

</LinearLayout>

3,然后Activity中代码如下:

public class LLLActivity extends AppCompatActivity {

    private RecyclerView recyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lll);
        // 初始化控件
        recyclerView = findViewById(recycleView);
        initRecycleView();
    }

    private void initRecycleView() {
        // 将网络请求获取到的json字符串转成的对象进行二次重组,生成集合List<Object>
        List<Object> list = sortData(网络请求成功返回的OpenRecordBean对象);
        LinearLayoutManager manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(manager);
        OpenRecordAddapter adapter = new OpenRecordAddapter(list);
        recycleView.setAdapter(adapter);
    }

    // 数据拆分重新组装的方法
    private List<Object> sortData(OpenRecordBean bean) {
        List<OpenRecordBean.DataBean> arrays = bean.getData();
        // 用来进行数据重组的新的集合arrays_obj,之所以泛型设为Object,是因为该例中的集合元素既可能为String有可能是一个bean
        List<Object> arrays_obj = new ArrayList<>();
        for (OpenRecordBean.DataBean array : arrays) {
            List<OpenRecordBean.DataBean.LogDOListBean> logs = array.getLogDOList();
            // 拿到String值添加进集合arrays_obj
            arrays_obj.add(array.getDateTitle());
            // 如果该标题下的集合里面有数据的话,遍历拿到添加进新集合arrays_obj
            if (logs != null && logs.size() > 0) {
                for (OpenRecordBean.DataBean.LogDOListBean log : logs) {
                    arrays_obj.add(log);
                }
            }
        }
        return arrays_obj;
    }

}

4,然后主要是OpenRecordAddapter,代码如下,对应的每种情况下的布局文件也很简单,只是textview赋值而已,所以此处省略:
这里使用了BaseRecyclerViewAdapterHelper加载多类型布局两种方式的第二种方式,即判断类型的代码放在了adapter中进行了判断,对于BaseRecyclerViewAdapterHelper框架使用还不熟悉的读者请看本人之前的博客:
安卓项目实战之:开源框架BaseRecyclerViewAdapterHelper的使用

public class OpenRecordAddapter extends BaseQuickAdapter<Object, BaseViewHolder>{

        public static final int ITEM_TITLE = 1;
        public static final int ITEM_CONTENT = 2;

        public OpenRecordAddapter(@Nullable List<Object> data) {
            super(data);
            // 第一步:动态判断
            setMultiTypeDelegate(new MultiTypeDelegate<Object>() {
                @Override
                protected int getItemType(Object o) {
                    // 当前例子中只有两种类型
                    if(o instanceof String){
                        // 加载布局1
                        return ITEM_TITLE;
                    }else if(o instanceof OpenRecordBean.DataBean.LogDOListBean){
                        // 加载布局2
                        return ITEM_CONTENT;
                    }
                    return 0;
                }
            });

            // 第二步:设置type和layout的对应关系
            getMultiTypeDelegate().registerItemType(ITEM_TITLE,R.layout.open_record_title)
                                  .registerItemType(ITEM_CONTENT,R.layout.open_record_content);
        }

        @Override
        protected void convert(BaseViewHolder helper, Object item) {
            // 第三步:设置不同布局下的组件数据
            switch (helper.getItemViewType()) {
                case ITEM_TITLE:
                    // 标题赋值
                    helper.setText(R.id.open_record_date_tv,(String)item);
                    break;
                case ITEM_CONTENT:
                    helper.setText(R.id.open_record_time_tv,((OpenRecordBean.DataBean.LogDOListBean)item).getUpdateTime())
                            .setText(R.id.open_record_terminal_tv,((OpenRecordBean.DataBean.LogDOListBean) item).getDeviceName())
                            .setText(R.id.open_record_name_tv,((OpenRecordBean.DataBean.LogDOListBean) item).getFullName())
                            .setText(R.id.open_record_door_NO_tv,""+((OpenRecordBean.DataBean.LogDOListBean) item).getOpenType());
                    break;
            }
        }
    }

经过上面四步,我们就做到了仅仅用了一个RecycleView就实现列表嵌套的效果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值