更新gridview时如何避免闪烁?

时间:2012-11-27 10:27:11

标签: android android-imageview android-gridview

我有一个gridview。我显示来自10个图像阵列的图像。 1分钟后我又添加了5张图片。要更新gridview,我使用以下代码。

aImgAdapterL.notifyDataSetChanged();  

aImgAdapterL 是我的ImgaeAdapter。新图像将显示出来 我的问题是在更新网格视图时,在图像更新期间发生一次闪烁或闪烁。是否有可能隐藏闪烁?

9 个答案:

答案 0 :(得分:7)

我有同样的问题,并且能够像这样解决它:

实际上,这是由于我的ListAdapter在整个列表刷新时没有正确管理的情况。如果是这样,您要做的是保持屏幕上已经显示的项目。

为此,在获得回收项目时,在适配器的方法getView中,您必须检查它是否已经是您要显示的项目。如果是这种情况,请直接退回。

@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;
}

答案 1 :(得分:5)

如果您的适配器具有稳定的ID,请覆盖hasStableIds以返回true

Grep android.GridView源代码here,它允许网格视图重用相同数据的视图,而不是完全重绘。这可能有助于OP的情况,因为默认情况下hasStableIds会返回false

答案 2 :(得分:1)

闪烁发生是因为更新UI很重。请检查天气是否正在执行cpu密集型功能,例如适配器的getview()中的图像裁剪。想法是保持getview()函数简单并执行过程密集单独线程中的逻辑。

答案 3 :(得分:1)

解决方案是在图像未更改时不重新加载。

在适配器中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,以便下次重新加载。

答案 4 :(得分:0)

使用nostra13's Universal Image Loader显示图片,在显示图片时设置一些动画。

...DisplayImageOptions.displayer(FadeInBitmapDisplayer)...

答案 5 :(得分:0)

这里我写了一个如何使用视图模式的详细示例:

  

With this approach you can avoid flickering.

答案 6 :(得分:0)

传递不考虑实际视图大小的ImageViewAware(而不是ImageView): Intead of:

imageLoader.displayImage(imageUri, imageView);

执行以下操作:

ImageAware imageAware = new ImageViewAware(imageView, false)
imageLoader.displayImage(imageUri, imageAware);

答案 7 :(得分:0)

简单的解决方案是 1)在适配器中有一个方法将新数据列表附加/重置到旧数组列表中,而不是调用notifyDataSetChanged() 当用户将滚动getview将被调用,因此列表将被更新。 它不应该闪烁。

e.g。 // Have a method in adapter class public void updateList(ArrayList<ABC> list) { /在这里输入代码`/添加到旧代码     oldList.addAll(列表); }

就是这样 `

答案 8 :(得分:0)

您应该启用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);

最后,您可以在更新期间覆盖网格视图并使用透明度进行播放。