我有一个网格视图。我正在显示 10 个图像阵列中的图像。1 分钟后,我又添加了 5 张图片。要更新 gridview,我使用以下代码。
aImgAdapterL.notifyDataSetChanged();
aImgAdapterL是我的 ImgaeAdapter。新图像正在显示。
我的问题是在更新图像更新期间发生闪烁或闪烁的网格视图时。是否可以隐藏闪烁?
我有一个网格视图。我正在显示 10 个图像阵列中的图像。1 分钟后,我又添加了 5 张图片。要更新 gridview,我使用以下代码。
aImgAdapterL.notifyDataSetChanged();
aImgAdapterL是我的 ImgaeAdapter。新图像正在显示。
我的问题是在更新图像更新期间发生闪烁或闪烁的网格视图时。是否可以隐藏闪烁?
我有同样的问题并且能够像这样解决它:
事实上,这是由于我ListAdapter
在刷新整个列表时没有正确处理这种情况。如果是这样,您要做的是保持屏幕上已显示的项目原样。
为此,在getView
Adapter 的方法中,当您获得回收物品时,您必须检查它是否已经不是您要显示的物品。如果是这种情况,直接退货就行了。
@Override
public View getView(int position, View convertView, ViewGroup container) {
ImageView imageView;
String src = this.getItem(position).getSrcThumbnail();
if (convertView == null) {
imageView = new ImageView(getContext());
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 120, getResources().getDisplayMetrics());
imageView.setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.MATCH_PARENT, height));
} else {
imageView = (ImageView) convertView;
// When you get a recycled item, check if it's not already the one you want to display.
String newSrc = (String) imageView.getTag();
if(newSrc.equals(src)){
// If so, return it directly.
return imageView;
}
}
loadBitmap(this.getItem(position).getSrcThumbnail(), imageView);
// Here you set the unique tag that allow to identify this item.
imageView.setTag(src);
return imageView;
}
如果您的适配器具有稳定的 ID,请覆盖hasStableIds
以返回true
。
Grep此处android.GridView
的源代码,它允许网格视图重用相同数据的视图,而不是进行完全重绘。这可能对 OP 的情况有所帮助,因为默认情况下返回.hasStableIds
false
解决方案是在图像未更改时不重新加载图像。
在你的适配器 getView() 做:
// schedule rendering:
final String path = ... (get path here);
if (holder.lastImageUrl == null || !holder.lastImageUrl.equals(path)
|| holder.headerImageView.getDrawable() == null) {
// refresh image
imageLoader.displayImage(imageUri, imageAware);
} else {
// do nothing, image did not change and does not need to be updated
}
成功时(添加 ImageLoadingListener)设置 holder.lastImageUrl = path,失败并取消设置 holder.lastImageUrl 为 null,以便下次重新加载。
闪烁是因为更新 UI 很繁重。请检查天气,您正在执行 cpu 密集型功能,例如适配器的 getview() 中的图像裁剪。想法是保持 getview() 函数简单,并单独执行处理密集型逻辑线程。
在显示图像时使用nostra13 的通用图像加载器,在显示时设置一些动画。
...DisplayImageOptions.displayer(FadeInBitmapDisplayer)...
不考虑实际视图大小的通过ImageViewAware
(而不是 ImageView):而不是:
imageLoader.displayImage(imageUri, imageView);
执行以下操作:
ImageAware imageAware = new ImageViewAware(imageView, false)
imageLoader.displayImage(imageUri, imageAware);
您应该启用 OpenGL 和硬件加速:
<application android:hardwareAccelerated="true" ...>
<uses-feature
android:name="string"
android:required=["true" | "false"]
android:glEsVersion="integer" />
您还可以对 gridview 的项目使用硬件缓存:
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
最后,您可以在更新期间覆盖您的网格视图并使用透明度。
简单的解决方案是 1) 在您的适配器中有一个方法,它将您的新数据列表附加/重置到旧数组列表中,而不是调用notifyDataSetChanged()
当用户滚动时,getview 将被调用,因此列表将被更新。它不应该闪烁。
例如
// Have a method in adapter class
public void updateList(ArrayList<ABC> list) {
/
在此处输入代码`/添加到旧的 oldList.addAll(list); }
就是这样`