如何避免细胞的调用notifyDataSetChanged()的PinterestLikeAdapterView当提神?提神、细胞、notifyDataSetChanged、PinterestLike

2023-09-06 02:38:03 作者:风一样的男子

我使用的是 PinterestLikeAdapterView库 显示来自互联网,这就好比一些图片一个gridview但具有不同高度的每个细胞。

I'm using the PinterestLikeAdapterView library to show some images from the internet, which is like a gridView but with different height for each cell.

由于我使用这个库从互联网上显示的图像,这是至关重要的,调用notifyDatasetChanged时不会造成一片混乱的看法。

Since I use this library to show images from the internet, it's crucial that when calling notifyDatasetChanged won't cause a mess on the views.

由于某些原因,调用此函数就会调用getView()方法与观点不同的位置。例如,尽管我没有滚动所有,并调用notifyDatasetChanged(或addAll情况下,它是一个ArrayAdapter),卡位0,将采取什么样的是8位的观点,对于位置1将采取的立场的看法7,等等...

For some reason, calling this function would call the getView() method with different positions for the views. for example, even though i didn't scroll at all, and call notifyDatasetChanged (or addAll in case it's an ArrayAdapter), for position 0 it will take what was the view of position 8, for position 1 it will take the view of position 7 , and so on...

这使得整个电网刷新其图像,因此它破坏了UX。

This makes the whole grid to refresh its images, and so it ruins the UX.

通常,在两者的GridView和ListView,克服清爽的方法是将被用于viewHolder内部认为的位置,并且如果它们是相等的,这意味着他们仍然匹配。

Usually, in both gridView and listView, the way to overcome refreshing is to put the position that was used for the view inside the viewHolder, and if they are equal, it means that they still match.

例如:

... 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
  ...
  }

不过,在这里,他们重复使用在不同的顺序其他意见,使这招不会在这里工作。

However, here they re-use other views in a different order so this trick won't work here.

由于这个问题,不仅是我得到的几乎所有的可见视图刷新,但由于我使用 DiskCacheLru库,它崩溃,因为它试图把2个相同inputSteam数据转换成使用2个线程相同的密钥。

Because of this issue, not only i get refreshes of almost all of the visible views, but since i use DiskCacheLru library, it crashes since it tries to put 2 identical inputSteam data into the same key using 2 threads.

我能做些什么? 这是在库中一个已知的bug?

What can I do? Is this a known bug in the library?

也许我用坏的方式来克服刷新?

Maybe I'm using a bad way to overcome refreshes?

现在,我使用内存高速缓存至少可以得到之前被缓存的项目,但是这更像是一个治愈不是疫苗......

for now, i use memory cache to at least get items that were cached before, but that's more like a "cure" than a "vaccine"...

推荐答案

简短的回答

使用图像装载库如毕加索的缓存,最近使用过的在内存中的图像,所以他们不'吨需要从网络重新加载。

Use an image loading library like Picasso that caches most recently used images in memory, so they don't need to be reloaded from the network.

的回答:

适配器视图做了名为查看的回收,其中浏览这是要显示的位置不再需要重新显示另一个。 (例如,当您向下滚动,浏览的消失在屏幕的顶部是重复使用,在屏幕上。底部的新位置)正因为如此,这是正常的为 getView()传递相同的查看的多个位置。

AdapterView does something called View recycling, where Views which are no longer needed to display a position are re-used to display another. (For example, as you scroll down, Views that disappear off the top of the screen are reused for new positions at the bottom of the screen.) Because of this, it's normal for getView() to be passed the same View for more than one position.

这是出于性能原因:人为增加新的浏览又硬又需要时间,因此适配器视图试图做它尽可能少。

This is done for performance reasons: Inflating new Views is hard and takes time, so AdapterView tries to do it as infrequently as possible.

在使用持有人,您存储引用的ImageView 的TextView 里面的物品的查看,所以你不必看他们与 findViewById()每一次 - 你通常不会存放具体到一个什么特定的位置,因为查看和它的持有人将的往往的可用于不同的位置。

When using a holder, you store references to ImageView and TextView children inside the item's View, so you don't have to look them up with findViewById() each time - you don't usually store anything specific to a particular position, because the View and its holder will often be used for different positions.

现在,当你调用 notifyDataSetChanged()适配器视图假设数据集已经完全改变。这是与位置8相关联的图像可能不再是present,或它可以与现在位置12相关联。因此,所有现有的浏览报废 - 而是因为适配器视图仍想避免夸大新浏览,他们正在重新用于显示新的数据,没有考虑什么位置,他们pviously显示$ P $。

Now, when you call notifyDataSetChanged(), AdapterView assumes that the data set has completely changed. The image that was associated with position 8 may no longer be present, or it may be associated with position 12 now. Consequently, all the existing Views are scrapped - but because AdapterView would still like to avoid inflating new Views, they're re-used to display the new data, with no regard for what position they were displaying previously.

这也解释了为什么 getView()被传递相同的查看针对不同岗位,为什么看到的位置是被刷新,当你调用 notifyDataSetChanged()。但如何避免图像刷新,破坏了用户体验?

This explains why getView() is being passed the same View for different positions, and why visible positions are being refreshed when you call notifyDataSetChanged(). But how to avoid having your images refresh, ruining the user experience?

使用图像装载库如毕加索的缓存,最近使用过的在内存中的图像,所以他们不'吨需要从网络重新加载。刷新仍将​​发生,但它会在瞬间完成的。

Use an image loading library like Picasso that caches most recently used images in memory, so they don't need to be reloaded from the network. The refresh will still happen, but it'll be instantaneous.