备忘:重构购物车遇到的问题

最近在重构APP的购物车功能,要实现的效果如下:
这里写图片描述
看上去挺简单的吧,之前用的布局是:

ScrollView+动态创建ListView(购物车有多少个供应商就add多少个ListView)

我重构购物车的目的:

1.布局修改,外层布局使用RecyclerView
2.全选能悬浮在购物车的底部,需要时展示

就这样两个改动,遇到了挺多问题,遇到问题就解决呗,以下是我记录的问题和重构时的想法。

重构一个模块我认为最重要的是理清逻辑,并且想好总布局该怎么做。
这个布局我最终用的布局如下,先写布局,展示里层数据,底部悬浮效果和实现功能先放一边。

RecyclerView(多布局,分为三块:配送中心(LinearLayout)+商品(RecyclerView)+底部价格(LinearLayout))

这个外层布局没啥好说的,做这一块出现问题了:
问题1:点击购物车-》点击其它模块-》点击购物车,重新获取数据-》刷新RecyclerView,这个本身逻辑没有问题,但是刷新时RecyclerView会自动移动到第二条数据,具体原因我还是没有找到,但我有解决方法。
解决:动态加载RecyclerView,每次跳转到购物车时动态创建RecyclerView。

接下来实现全选,单选,删除等逻辑,购物车的功能,这部分问题还是挺多的,点击底部全选要刷新商品选择状态,单个商品选择状态改变要刷新底部全选状态。
问题2:第二层RecyclerView中没有数据时,需要手动更新第一层RecyclerView,将其对应数据的头部、底部布局去掉。
解决: 在删除单个商品后判断该部分商品是否isEmpty,是空证明需要刷新,在设置数据的Fragment中将该数据源删除,然后adapter.notifyDataSetChanged();(可使用EventBus)
if (ArrayUtil.isEmpty(goodses)) {
       presenter.notifyData(tag);
 }
问题3:点击某个商品,需刷新对应的底部布局。
解决:和问题2差不多,在某个商品状态改变时,在设置数据的Fragment中刷新对应的position。
问题4:由问题3产生,设置数据的Fragment中刷新对应的position。
cartListAdapter.notifyItemChanged(msg.arg1);
在运行时会报错,直接导致程序崩溃。
原因:前几天查的,不知道记得对不对。在RecyclerView绘制或者滑动时刷新某个数据。
解决:这个方法能解决就没有试别的方法了。
Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                cartListAdapter.notifyItemChanged(msg.arg1);
            }
        }
    };

功能这块折腾完了,没毛病。接下来看那个悬浮效果了,这可是个大坑呀。
思路:第一层RecyclerView的滑动事件addOnScrollListener获取到最后一个可见的position,根据position判断是哪个配送中心对应部分,然后展示对应的底部布局数据。
好,一堆问题来了。
问题5:addOnScrollListener是滑动事件,如果点击了某个地方的商品,不滑动不会更新底部数据。
解决:在某个商品状态改变时,手动更新底部布局数据。这里还需判断底部展示的position是否和改变的position相等。
问题6:例:当商品数据为一个时,还不会占满屏幕,它的底部还是会展示出来,很丑。
解决:这个问题我选择迂回战术解决,不会占满屏幕就证明数据太少了,它也不能滑动,所以外层RecyclerView第一个可见position就会一直是0,判断   position!=0  时才展示底部布局就行。
问题7:点击全选多次时,程序直接崩溃。
解决:这个问题就厉害了,找这个问题找的最久。在改变底部的选择状态时需要去刷新它对应的商品选择状态,也就是刷新里层RecyclerView,之前刷新用的外层RecyclerView对应的notifyItemChanged();
改成里层RecyclerView对应adapter.notifyDataSetChanged() 就可以了。
cartGoodsAdapters.get(position).setGoodsList(goodses);
cartGoodsAdapters.get(position).notifyDataSetChanged();

外层RecyclerView滑动逻辑:

  //设置RecyclerView的滑动事件
        recycler_cart1.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                int firstItemPosition = 0;
                int lastItemPosition = 0;
                RecyclerView.LayoutManager layoutManager = recycler_cart1.getLayoutManager();
                if (layoutManager instanceof LinearLayoutManager) {
                    firstItemPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
                    lastItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
                    if (firstItemPosition != 0 && (lastItemPosition % 3 == 1 || lastItemPosition % 3 == 2)) {
                        if (view_center.getVisibility() != View.VISIBLE)
                            view_center.setVisibility(View.VISIBLE);
                        //当前是哪一组数据
                        int position = lastItemPosition / 3;
                        if (curShowPosition != position) {
                            initIsShowBottomView(position);
                        }
                    } else {
                        view_center.setVisibility(View.GONE);
                    }
                }
            }
        });

    private void initIsShowBottomView(int position) {
        if ("0".equals(couldReplenishment) && orderTypes.get(position) != 2) {
            tvReplenishment.setVisibility(View.VISIBLE);
            couldReplenishment = "0";
        } else {
            tvReplenishment.setVisibility(View.GONE);
            couldReplenishment = "1";
        }

        setBottomOnClickListener(position);
        setViewData(position);
        curShowPosition = position;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值