GridView getView问题

时间:2013-01-24 02:54:07

标签: java android gridview lazy-loading universal-image-loader

在我的GridView的getView()方法中,我正在执行以下操作:

public View getView(int position, View convertView, ViewGroup parent) {
       convertView = this.inflater.inflate(..);
       ImageView image = (ImageView) convertView
                .findViewById(R.id.imageButton1);
       imageLoader.displayImage("URL/"
                + sampleArray.get(position), image);

sampleArray这是我在创建适配器时加载的数组。在延迟加载(使用此工具:https://github.com/nostra13/Android-Universal-Image-Loader)这些图像时使用它,并且基本上是图像URL的一部分,用于确定要加载的图片。现在,据我所知,最佳做法是只有在视图时才会显示:

if(convertView == null){
   this.inflater.inflate(...);

当我这样做时,它实际上更快,但图像加载很奇怪。如果我向下滚动并向上滚动,图像在行内切换,意味着在第一行中,第一列图像可能会随第二列图像随机切换。我正在使用的数组(sampleArray)不会更改。我知道它与position和getView()有关,但我不确定为什么会出现这种情况。

如果我按照我现在的方式(第一块代码)这样​​做,这意味着我每次都要充气,它工作得很好,但加载速度很慢。为什么这种行为会像这样?

提前致谢。

修改

这就是我认为正在发生的事情。 GetView()被多次调用,它在某种程度上与“position”参数不同步,导致从数组中挑出错误的元素。我仍然对它感到困惑。

2 个答案:

答案 0 :(得分:0)

您是否尝试清理原始图片:

image.setImageBitmap(null);

我检查image loader的源代码,其中一种方法如下:

public void displayImage(String uri, ImageView imageView, DisplayImageOptions options) 

我认为你也可以尝试将选项设置为“resetViewBeforeLoading = true”

我认为奇怪的事情发生的原因是,视图由gridview回收,在显示之前,仍然使用原始位图,在加载器使用新位图附加它之前。

如果它仍然不起作用,请知道。

修改

我做了更多调查,我认为是因为回收利用。 让我更清楚地解释一下:

原因:

假设我们的数据中共有12个单元格 在屏幕上,只有9个视图可见

一开始,gridview将在屏幕上创建并显示9:

view_1_1 view_1_2 view_1_3

view_2_1 view_2_2 view_2_3

view_3_1 view_3_2 view_3_3

滚动(向上滚动,显示第4行)后,此时网格视图会将view_1_1,view_1_2,view_1_3放入回收站。 然后从recycle-bin获取第4行的3个视图,这些视图作为“convertView”放在getView中 因此,view_1_1,view_1_2,view_1_3将被重复使用。

假设在开头,视图附有位图

view_1_1:bitmap_1_1

view_1_2:bitmap_1_2

view_1_3:bitmap_1_3

当这些视图被回收并显示在第4行时,由于位图是异步加载的,因此bitmap_1_1,bitmap_1_2,bitmap_1_3将显示在第4行,之后将被这些新位图替换。

如何确认

1.调试网格视图的一种方法我喜欢在图像上放一些“id”,简单的方法就是把“ImageView”放到String() 在每个imageView上方放置一个叠加视图,并在其中写入id,如:

String s = viewInfoHolder.imageView.toString();
viewInfoHolder.overlay.setText(s.substring(s.length() -3));//last 3 chars are enough and cleanup

2.为了使替换变慢,修改

com.nostra13.universalimageloader.core.LoadAndDisplayImageTask

方法的最后一行:

public void run() 

从:

handler.post(displayBitmapTask);

为:

handler.postDelayed(displayBitmapTask, 2000);

您可以准确了解网格视图的工作原理。

希望它有用:)

答案 1 :(得分:0)

你应该使用

.resetViewBeforeLoading()

可能

.showStubImage(R.drawable.empty_image)
初始化UIL时,在DisplayImageOptions上

。 这将在加载之前重置视图。 这是必需的,因为您正在重复使用gridview上的视图。