背景
我正在使用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(使用前将#替换为@)