recyclerview更新进度时滑动列表出现闪烁或跳动问题的解决方案。

1.问题描述:在使用高德sdk下载离线地图的业务场景中,需要实时更新下载进度。当我通过notifyItemChanged更新item时却发现滑动列表时会出现:在更新时屏幕外的item滑动进入屏幕时突然消失,列表跳动并移动到顶部,看起来是很奇怪的跳动。

2.引起原因:在短时间内重复多次使用notifyitemchange导致的holder视图重绘,如果实验就可以发现,在更新发生异常跳动之后的间隔再滑动可以看到holder(item)并没有消失,只是在更新时发生了一次重新绘制,所以才出现这种消失的列表跳动。

3.解决方案和经历:困扰了几天的问题,在不断地百度和ai之后终于解决。网上得到的废话大概有以下类型。

1.提醒不要用notifydatasetchange,使用notifyitemchange。(无语...)

2.重写onbindviewholder() 方法,在adapter中有这个方法的重载

public void onBindViewHolder(@NonNull ManagerViewHolder holder, int position, @NonNull List<Object> payloads)

最终我的解决方案是使用:recyclerview.setHasFixedSize(true);更新完item记得重新设回false,否则可能影响其他更新方法。

4.详细讲解:

recyclerview.setHasFixedSize(true);的作用:通知列表数据更新时大小固定,而大小固定就会让recyclerview不再重新计算自身的宽高和长度。此时holder也就不会一直重绘。

5.代码实现:

//这里获取到更新的数据,高德提供了一个包含进度ratio属性的对象,这里返回的就是更新过ratio的对象
MKOLUpdateElement update = mkOfflineMap.getUpdateInfo(state);     
if (update != null) {
    //列表在fragement中,调用更新
  managerFragment.updateItem(update);
}


//fragment中的更新方法
public void updateItem(MKOLUpdateElement element){
        if (adapter!=null){
            manager_list.setHasFixedSize(true);
            adapter.updateItem(element);
            manager_list.setHasFixedSize(false);
        }
    }


//adapter中的更新方法,查找数据源中对应的item并更新
 public void updateItem(MKOLUpdateElement element) {
        int position = -1;
        for (int i = 0; i < localMapList.size(); i++) {
            if (localMapList.get(i).cityID == element.cityID) {
                position = i;
                break;
            }
        }
        if (position != -1) {
            localMapList.get(position).ratio=element.ratio;
            localMapList.get(position).status=element.status;
            //如果只传position会更新整个item,如果传递一个ratio可以实现重载方法来更新局部
            notifyItemChanged(position,element.ratio);
        }
    }

//可以到上面就结束,不过可以实现这个方法的重载来只更新进度组件
/**
*public void onBindViewHolder(@NonNull ManagerViewHolder holder, int position, @NonNull List<Object> payloads) 
*
/
 if (payloads.isEmpty()) {
            bind(holder,position);
        } else {
            // 如果有payload,表示部分数据更新
            for (Object payload : payloads) {
                if (payload instanceof Integer) {
                    //更新你的进度,payload
                }
            }
        }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值