杜绝嵌套列表啦

自己像之前购物车列表的也都做过,不过那时候都是用了ListView+ListView嵌套解决,RecyclerView还没出来,编辑全选等逻辑的时候一大堆的逻辑、点击事件,导致自己以后看这些代码也都很吃力,现在又碰到啦,想着就两个字:杜绝!😂

就直接拿淘宝的我的订单了,订单列表+每个订单中商品列表:


类似淘宝这种我的订单.png
思考
  • 方案一:淘宝是咋实现的,无论从性能还是效果都是杠杠的,可宝宝我的确不知道啊。😢
  • 方案二:ListView+ListView嵌套、RecyclerView+RecyclerView嵌套(这种没尝试过),或者组合嵌套本宝宝都一律不想用,都不知道哪一天活着啥时候就出现不可预知的问题。据查证,ListView嵌套的话,在数据量多的情况下,页面可能会出现崩溃,但是我以前做的列表现在崩溃没崩溃我就不知道了。🙀
  • 方案三:RecyclerView很强大,可以有多种不同的布局,最近很多介绍VLayout布局框架可以适配多种不同布局,但是我也仔细研究了下,用RecyclerView也可以,不过要将你返回的数据格式重新组装成适用RecyclerView的模型数据,我是考虑到万一产品哪天说我想来个联动编辑操作,那就完完了,所以这种方案也不做考虑吧,如果是公司新开的一些项目,或者引入框架影响比较小的项目,我可能会考虑用第三方的框架。
  • 方案四:ExpandableListView:树形菜单展开收起用的比较多,在这里仔细考虑了下似乎是可以尝试的选择,毕竟我也不知道人家牛逼的是怎么实现的啊,总要交个功能出来吧。
实现

ExpandableListView用法大家应该都会,就是要注意几点的地方:

  1. 始终保持展开:
private void expandListView() {
    for (int i = 0; i < mAdapter.getGroupCount(); i++) {
        mListView.expandGroup(i);
    }
}
  1. 禁止group的展开收起事件:
mExpandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
               // 始终返回true
                return true;
            }
        });
  1. 底部按钮部分的显示,只能放在childView中处理,作为childView的一部分,在显示最后一个childView的时候显示该view,其他情况都隐藏,这点处理还是有点坑爹的,毕竟人家ExpandableListView用在这里的确有点牵强。
布局拆分.png

getChildView()部分代码:

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ChildHolder holder = null;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.item_order_content, parent, false);
            holder = new ChildHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ChildHolder) convertView.getTag();
        } 
        // getChildView方法中isLastChild可以来判断是否是最后一个childView显示
        if (isLastChild) {
            holder.orderBottomLl.setVisibility(View.VISIBLE);
            OrderEntity order = (OrderEntity) getGroup(groupPosition);
            holder.setButtons(order);
            formatBottomPrice(holder.orderBottomPriceTv, order);
        } else {
            holder.orderBottomLl.setVisibility(View.GONE);
        }
        // 省略部分代码
        ......
        return convertView;
    }
效果

最终效果实现也都👌了,不过其实我想要说的不是这里,是底部按钮的处理,这个在以前都是通过订单的状态来判断,在哪些订单状态下显示哪些按钮,基本上可以说是固定的,只要通过订单状态来判断显示与隐藏即可,但是如果服务器端跟你说底部按钮需要动态返回呢。听到的第一反映就是NO!NO!NO!第一想法是那我启不是要不断的动态添加按钮,删除按钮,这界面能扛的住么。所以说啊,事情不是绝对的,不要不思考就予以否定,解决方案还是有的。


底部按钮.png
动态按钮处理

服务器返回格式:Map<key, value>,key是唯一的,value是按钮文字;

  1. 封装一个操作按钮实体类:
public static class OperatorButton implements Comparable<OperatorButton> {
        public String buttonKey;
        public String buttonValue;
        // 顺序:ui界面中按钮从左到右的顺序
        public int sort;
        // 按钮的样式,可以添加你自己需要的...
        public int textColor;
        public int bgResource;
        // 为每种按钮定义点击事件的ID
        public int clickId;
}
  1. 解析json的时候根据不同的key,创建操作按钮类,添加到list中;
  2. 排序list集合,Collections.sort(list);
  3. 在adapter中循环list,当然事先放三个按钮(因为我的UI界面最多只有三个),依次从左到右取出按钮显示,设置,剩余按钮隐藏;
       /**
         * 底部按钮处理
         * @param entity
         */
        public void setButtons(final OrderEntity entity) {
            List<OrderEntity.OperatorButton> list = entity.operatorList;
            // 操作按钮list是空的,直接隐藏底部view
            if (ListUtils.isEmpty(list)) {
                buttonsLl.setVisibility(View.GONE);
                return;
            }
            //   显示底部view,但是事先隐藏三个按钮
            buttonsLl.setVisibility(View.VISIBLE);
            btnOneTv.setVisibility(View.GONE);
            btnTwoTv.setVisibility(View.GONE);
            btnThreeTv.setVisibility(View.GONE);
            for (int i = 0; i < list.size(); i++) {
                final OrderEntity.OperatorButton bean = list.get(i);
                // 为了避免服务器返回超过3个以上的按钮,还是做下判断,以免数组越界,而且有可能返回不在ui上显示的状态,我就判断了下按钮文字是否为空
                if (i < buttons.size() && !StringUtils.isNull(bean.buttonValue)) {
                    TextView txt = buttons.get(i);
                    txt.setVisibility(View.VISIBLE);
                    txt.setText(bean.buttonValue);
                    if (bean.textColor != 0) {
                        txt.setTextColor(mContext.getResources().getColor(bean.textColor));
                    }
                    if (bean.bgResource != 0) {
                        txt.setBackgroundResource(bean.bgResource);
                    }
                    txt.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            // mListener是自定义的点击事件接口,外部activity可以实现
                            if (mListener != null) {
                                mListener.onClick(bean.clickId, entity);
                            }
                        }
                    });
                }
            }
        }
    }

😂这是我暂时能想到的比较顺的处理方式,当然还有其他方式,比如我的同事就提供了一种,让按钮实现一个接口,这个接口专门处理根据key来动态设置按钮的样式等,但是我当时想这样的话我可能要自定义按钮,里面根据key来完成处理,也可以相对麻烦了些。

最后,这只是我自己处理的一种方式,还有其他方式的大家可以一起交流下,一个人的思维有限,一起交流就会有更多不同的方案。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容