为 PinterestLikeAdapterView 调用 notificationDataSetChanged() 时如何避免刷新单元格?

2023-11-25

背景

我正在使用PinterestLikeAdapterView 库显示一些来自互联网的图像,它类似于 gridView 但每个单元格的高度不同。

问题

由于我使用这个库来显示来自互联网的图像,因此调用notifyDatasetChanged 时不会导致视图混乱是至关重要的。

由于某种原因,调用此函数会调用具有不同视图位置的 getView() 方法。例如,即使我根本没有滚动,并调用notifyDatasetChanged(或addAll,如果它是ArrayAdapter),对于位置0,它将采用位置8的视图,对于位置1,它将采用位置的视图7 等等...

这使得整个网格刷新其图像,从而破坏了用户体验。

通常,在gridView和listView中,克服刷新的方法是将视图使用的位置放在viewHolder中,如果它们相等,则意味着它们仍然匹配。

例如:

... getView(...)
  {
  //<=inflate a new view if needed 
  //avoid refreshing view in case it's still the same position:
  if(position==holder.position)
    return rootView;
  holder.position=position;
  //<=update the view according to its data
  ...
  }

然而,在这里他们以不同的顺序重用其他视图,因此这个技巧在这里不起作用。

由于这个问题,我不仅刷新了几乎所有可见视图,而且因为我使用DiskCacheLru 库,它崩溃了,因为它尝试使用 2 个线程将 2 个相同的 inputSteam 数据放入同一个密钥中。

问题

我能做些什么? 这是库中的已知错误吗?

也许我使用了一种糟糕的方法来克服刷新?

现在,我使用内存缓存至少获取之前缓存的项目,但这更像是“治愈”而不是“疫苗”......


简短回答:

使用图像加载库,例如Picasso将最近使用的图像缓存在内存中,因此不需要从网络重新加载它们。

长答案:

AdapterView做一些叫做View回收,哪里Views不再需要显示一个位置的部分将被重新用于显示另一个位置。 (例如,当您向下滚动时,Views从屏幕顶部消失的部分会重新用于屏幕底部的新位置。)因此,这是正常的getView()相同地通过View担任多个职位。

这样做是出于性能原因:膨胀新的Views很难并且需要时间,所以AdapterView尝试尽可能少地这样做。

使用支架时,您可以存储对ImageView and TextView物品内的孩子View,所以你不必查找它们findViewById()每次 - 您通常不会存储特定于特定位置的任何内容,因为View其持有者将often用于不同的位置。

现在,当你打电话时notifyDataSetChanged(), AdapterView假设数据集已完全更改。与位置 8 关联的图像可能不再存在,或者现在可能与位置 12 关联。因此,所有现有的Views被废弃 - 但因为AdapterView仍然希望避免膨胀新的Views,它们被重新用于显示新数据,而不考虑它们之前显示的位置。

这解释了为什么getView()正在通过相同的View对于不同的位置,以及为什么当您调用时可见位置会被刷新notifyDataSetChanged()。但如何避免图像刷新而破坏用户体验呢?

使用图像加载库,例如Picasso将最近使用的图像缓存在内存中,因此不需要从网络重新加载它们。刷新仍然会发生,但会是瞬时的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为 PinterestLikeAdapterView 调用 notificationDataSetChanged() 时如何避免刷新单元格? 的相关文章