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 } } }
2万+

被折叠的 条评论
为什么被折叠?



