Android:玩转订单详情三层数据只需要一层RecyclerView,并不需要嵌套View

大家好,我们又见面了,很高兴证明我又有东西跟大家分享了上星期我写了一篇关于[Android:玩转购物车界面和逻辑只需要一层Recyclerview,一个二层for循环和三个属性](http://www.jianshu.com/p/6c3328f87fc9),反响比我想象中好很多,而且有幸被DiyCode转发了,我自己本人也没去投稿也是有一个朋友告诉我才知道这件事~不管怎么一个阴差阳错,这也证明最近一段时间没有白做项目。

有幸被DiyCode转发.png

连上实习出社会工作一年多了,相比于其他办公室政治的职业,真心觉得程序猿是比较和谐的,无论是谁只要是程序猿坐在一起都可以聊大半天,互相去分享经验和学习。当然这次来不是为了跟人炫耀什么,只是想来再次分享一些更劲爆的项目经验,也是关于商城的,不过这次是购物车之后的订单列表。我们先看看界面需求:

界面需求.png

那接下来就分析一下我自己的理解和做法。
如果不想听我啰嗦的人可以直接去下载源码源码下载链接
这样看上去,我们就看到有三个不同的item。
1.一张大订单的含有所有信息的item:

一张大订单.png

2.一张大订单里面分为一张张小订单,每张小订单就代表一间店铺的所有商品,而且每间商铺的第一个商品需要带小订单编号和商铺名字的header:


含有商铺名和订单编号header的item.png

3.下面的就是小订单内非第一件商品的item(不含header):


小订单内非第一件商品.png

看完这个界面需求,相信很多人都跟我一样,觉得用两层嵌套的RecyclerView、隐藏和显示商品的头布局不就可以完成这样的界面了?
确实做界面的时候我是这样做的,但是当把数据插入的时候,嵌套View的问题就无缘无故出现了:
两层RecyclerView嵌套的效果.gif

可能gif图大家还看不出问题。


两层RecyclerView嵌套解析图一.png

明明是一张大订单里面有两张不同商铺的小订单,总共有五件商品,两张小订单号分别尾数是133和601,但当我们上拉RecyclerView然后再下拉回去的时候,我发现:

两层RecyclerView嵌套解析图二.png

本来同属于一张大订单的尾数为133和601的两张小订单本来5件商品却无缘无故消失了剩下一件商品~
得到这种结果令我非常诧异,无论我用什么样的方式去验证这样的嵌套RecyclerView的做法,都是会出现这样的情况。我的一位从我学习Android以来一直帮助我的师兄,他也去检查过我写的xml布局和adapter,也没发现问题,但显示的时候总会出现布局丢失的情况。
最后我发现这是一条死胡同,一个我无法解释的bug。
<u>其实在用RecyclerView嵌套的时候我已经发现很多无缘无故的显示bug,所以我劝大家还是少用布局嵌套,不然就像我这样作死~
</u>
既然这样走嵌套RecyclerView是一条死胡同,那只能用不嵌套的做法来做了,下面我就讲讲我的师兄,他给我的一个做法。确实在这里的做法和逻辑都是师兄写的,我只是做了实现和笔录~
看这种做法之前,我们先看看后台返回来的数据是怎么样的,才好思考往下怎么去做:

数据结构一:大订单.png
数据结构二:大订单里面有若干个商品.png
数据结构三:每个商品信息含有该商品的商铺信息,每间商铺就是一张小订单.png

我把以上三张图的数据结构简化一下:

"result":{
        "大订单List":[
            大订单1{...},
            大订单2 {
                大订单的相关信息
                "商品List":[
                    "商品1"{
                          "商品信息"
                          "商铺信息":{
                             商品所在商铺的信息, 即小订单信息
                        } 
                    },
                    "商品2"{...},
                    "商品3"{...},
                 ]
            },
            大订单3{...}
        ]
    }

看上去,三层数据怎么把他用一层RecyclerView显示出来呢?这里,不得不说师兄想的方法非常有意思。

他把这里的所有数据分成三种数据类型,并把RecyclerView分成三种不同的布局,对返回来的数据用不同的对象进行排序并且把排好序的数据最后放进一条List<Object>,让adapter去判断该显示哪种布局

三种不同的对象.png

(1)GoodsOrderInfo 表示每个小订单的头部信息(订单号、订单状态、店铺名称)

小订单的头部信息.png

(2)OrderGoodsItem 表示小订单中的商品

小订单中的商品.png

(3)OrderPayInfo 表示大订单的支付信息(金额、订单状态)

大订单的支付信息(金额、订单状态).png

我们来看看代码:

public class OrderDataHelper {
    /**
     * List<Object>有三种数据类型:
     * 1、GoodsOrderInfo 表示每个小订单的头部信息(订单号、订单状态、店铺名称)
     * 2、OrderGoodsItem 表示小订单中的商品
     * 3、OrderPayInfo 表示大订单的支付信息(金额、订单状态)
     * @param resultList
     * @return
     */
    public static List<Object> getDataAfterHandle(List<OrderSummary> resultList) {
        List<Object> dataList = new ArrayList<Object>();
        //遍历每一张大订单
        for (OrderSummary orderSummary : resultList) {
            //大订单支付的金额和订单状态
            OrderPayInfo orderPayInfo = new OrderPayInfo();
            orderPayInfo.setTotalAmount(orderSummary.getTotalPrice());
            orderPayInfo.setStatus(orderSummary.getStatus());
            orderPayInfo.setId(orderSummary.getId());
            //小订单商品
            List<OrderGoodsItem> orderDetailList = orderSummary.getOrderDetailList();
            Map<String, List<OrderGoodsItem>> orderGoodsMap = new HashMap<String, List<OrderGoodsItem>>();
            Map<String, GoodsOrderInfo> orderInfoMap = new HashMap<String, GoodsOrderInfo>();
            //遍历每个大订单里面的商品
            for (OrderGoodsItem orderGoodsItem : orderDetailList) {
                //获取商品里面的商铺信息的订单号
                String orderCode = orderGoodsItem.getOrder().getOrderCode();
                orderGoodsItem.setOrderid(orderSummary.getId());
                //拿到相对应订单号的所有商品
                List<OrderGoodsItem> goodsList = orderGoodsMap.get(orderCode);
                //如果goodsList为空,则新建;
                //而且把这个订单号的orderGoodsMap持有订单的对象goodsList
                if (goodsList == null) {
                    goodsList = new ArrayList<>();
                    orderGoodsMap.put(orderCode, goodsList);
                }
                //goodsList添加商品的对象,因为orderGoodsMap
                //已经持有这个订单号的goodsList对象,所以不用重新put         
                goodsList.add(orderGoodsItem);
                //把小订单的店铺信息赋给GoodsOrderInfo对象,并加入到orderInfoMap
                GoodsOrderInfo orderInfo = orderInfoMap.get(orderCode);
                if(orderInfo == null) {
                    orderInfo = new GoodsOrderInfo();
                    orderInfo.setOrderCode(orderCode);
                    orderInfo.setShopName(orderGoodsItem.getOrder().getShopName());
                    orderInfo.setStatus(orderGoodsItem.getOrder().getStatus());
                    orderInfoMap.put(orderCode, orderInfo);
                }
            }
            //把所有数据按照头部、内容和尾部三个部分排序好
            Set<String> keySet = orderGoodsMap.keySet();
            for(String orderCode : keySet) {
                dataList.add(orderInfoMap.get(orderCode));
                dataList.addAll(orderGoodsMap.get(orderCode));
            }
            dataList.add(orderPayInfo);
        }
        return dataList;
    }
}

代码很简单,只是一个简单的工具类,就把后台返回来的三层数据分为了一层,一条已经排好序的List<Object>。
然后我们就去看看简单的adapter数据显示:

变量的声明.png

下面就是拿到数据之后的使用:


使用.png

看看adapter怎么写:

类型.png
根据不同的对象返回要显示相应布局的参数.png
根据不同的参数显示相应的ViewHolder.png
根据不同的布局做相关的处理.png

三种布局最后拼接成了理想的界面.png

是不是很简单?其实师兄的这种做法同时也利用了RecyclerView可以显示返回不同的布局,然后通过三种不同的布局拼接来完成一层RecyclerView控制三层数据的相关做法,而且这样做并不会用到该死的嵌套RecyclerView,不会有那该死的不知道拿来的显示bug,我个人觉得真的很赞!你们觉得如何?
感兴趣的同学可以下载源码去慢慢研究,有不同做法的同学可以提出来~
源码下载链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容