仿淘宝我的订单:RecyclerView嵌套RecyclerView,解决刷新图片闪烁问题

11,105 阅读2分钟

先看效果图

1.recyclerview1嵌套recyclerview2,adpter1是recyclerview1的适配器,adapter2是recyclerview2的适配器

2.页面解析:截图那部分是recyclerview1的一个item,画红框的是recyclerview2,可以明显看到,图片是recyclerview2的item

3.我的问题点:adpter1中onBindViewHolder方法中直接new一个adapter2,然后设置到recyclerview2上,导致每次刷新adapter都是一个新的对象。

网上说解决图片闪烁的处理方法:(mAdapter.setHasStableIds(true);) + (重写adpater的getItemId,保证itemId的唯一性)+调用notifyDataSetChanged()

还有:给imageview.setTag()

(其实是可以解决的,解决不了的话,肯定自身代码还有问题,比如我这个例子)

这些方法对我来说都没有作用,每次断点进去getTag都是null,我就纳了闷了。后来修改了adpter1中的代码: 在onBindViewHolder方法中,判断onBindViewHolder的适配是否为null,为空再new

 if (helper.itemOrder_GoodInfor.getAdapter() == null) {
    OrderListGoodsAdapter1 adapter = new OrderListGoodsAdapter1(mContext);
    adapter.setHasStableIds(true);
    GridLayoutManager managerBtn = new GridLayoutManager(mContext, 1);
    helper.itemOrder_GoodInfor.setLayoutManager(managerBtn);
    ((SimpleItemAnimator) helper.itemOrder_GoodInfor.getItemAnimator()).setSupportsChangeAnimations(false);
    helper.itemOrder_GoodInfor.getItemAnimator().setChangeDuration(0);// 通过设置动画执行时间为0来解决闪烁问题

    helper.itemOrder_GoodInfor.setTag(R.id.itemOrder_GoodInfor, item.getId());
    helper.itemOrder_GoodInfor.setAdapter(adapter);

    helper.itemOrder_GoodInfor.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            return   helper.itemView.onTouchEvent(event);
        }
    });

//            helper.itemOrder_GoodInfor.setOnItemClickListener(new ByRecyclerView.OnItemClickListener() //{
//                @Override
//                public void onClick(View v, int position) {
//                    Object tag = helper.itemOrder_GoodInfor.getTag(R.id.itemOrder_GoodInfor);
//                    MyOrderDetailActivity.start(mContext, (int) tag);
//                }
//            });

//            adapter.setNewData(item.getGoods());
        adapter.updateData(item.getGoods());
    } else {
        ((OrderListGoodsAdapter1) helper.itemOrder_GoodInfor.getAdapter()).updateData(item.getGoods());
    }

adapter2我这边是OrderListGoodsAdapter1部分代码如下:给Imageview orderCenter_iv设置setTag

    public void updateData(List<OrderGroup.GoodsBean> dataSet) {
        this.listData = dataSet;
        notifyDataSetChanged();
    }
    private void onBindMainViewHolder(ViewHolder binding, int position) {
        OrderGroup.GoodsBean item = listData.get(position);
        /**
         * 解决滑动recyclerview导致glide图片加载闪烁
         * 1.利用setTag
         * 2.Glide设置skipMemoryCache(true),跳过缓存
         */
        String tag = (String)binding.orderCenter_iv.getTag(R.id.orderCenter_iv);
        String image = item.getImage();
        if (item.getSpec_image() != null && !"".equals(item.getSpec_image())){
            image = item.getSpec_image();
        }
        if (!image.equals(tag)) {
            // 加载图片
//            GlideUtil.imageUrl(articleViewHolder.iv, bean.getImage(), height, height);

            Glide.with(mContext).load(image)
                    .transform(new CropSquareTransformation())
                    .dontAnimate()
                    .skipMemoryCache(false)
//                    .apply(options)
                    .into(binding.orderCenter_iv);
            binding.orderCenter_iv.setTag(R.id.orderCenter_iv,image);
        }

        String tag1 = (String)binding.orderCenter_iv.getTag(R.id.orderCenter_iv);
        binding.orderCenter_goodName.setText(TextViewUtils.noEmpty(item.getGoods_name()));
        binding.tv_model.setText(TextViewUtils.noEmpty(item.getGoods_attr()));
        binding.tv_price.setText(TextViewUtils.noEmpty(item.getGoods_price()));
        binding.tv_count.setText("x" + +item.getTotal_num());
    }

那么列表刷新图片就不会闪烁,但是点击item项进入商品详情,发现数据错乱了!!!!

原来我是在recyclerview2中setOnItemClickListener,所以获取的商品id都是错误的,后来改在recyclerview1中setOnItemClickListener,发现点击被嵌套的列表recyclerview2没有反应。原来是recyclerview嵌套recyclerview导致的冲突。最终解决方法: recyclerview2设置setOnTouchListener监听,将焦点放弃,给recyclerview1的item处理

            helper.itemOrder_GoodInfor.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent event) {
                    return   helper.itemView.onTouchEvent(event);
                }
            });

然后在adapter1中设置item的点击监听

        helper.itemView.setOnClickListener(view -> {
            MyOrderDetailActivity.start(mContext, item.getId());
        });

好了,完美解决! 注意点:因为后端偷懒,这个接口并没有做分页处理,所以分页是否会起因其他问题,需要自己处理哦。