旋转屏幕或滚动时,getView()图像的顺序错误

时间:2012-01-23 12:43:11

标签: java android

我有一个将缩略图加载到gridView中的ImageAdapter。

public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;

    if (convertView == null) {
        imageView = new ImageView(mContext);
        imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(8, 8, 8, 8);

        LoadThumbs downloader = new LoadThumbs(imageView);

        downloader.execute(Loggedin.mImageIds.get(position));

    } else {
        imageView = (ImageView) convertView;
    }

    return imageView;

}

mImageIds是一个字符串ArrayList,其中包含我服务器上的url图像。我的LoadThumbs类只是在asynctask中下载图像。

public class LoadThumbs extends AsyncTask<String, Void, Bitmap> {
private String url;


private final WeakReference<ImageView> imageViewReference;    

public LoadThumbs(ImageView imageView) {
    imageViewReference = new WeakReference<ImageView>(imageView);

}

protected Bitmap doInBackground(String... params) {
    url = params[0];
    try {
        return BitmapFactory.decodeStream(new URL(url).openConnection().getInputStream());
    } catch (MalformedURLException e) {
        e.printStackTrace();
        return null;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

protected void onPostExecute(Bitmap result) {
    if (imageViewReference != null) {
        ImageView imageView = imageViewReference.get();
        if (imageView != null) {

            imageView.setImageBitmap(result);
        }
    }
}

protected void onPreExecute() {
    if (imageViewReference != null) {
        ImageView imageView = imageViewReference.get();
        if (imageView != null) {

            imageView.setImageResource(R.drawable.loadcircle);
        }
    }
}

}

它有效,它会下载图像。但是当我旋转屏幕时,图像以相反的顺序出现。

已经有过几次讨论,但那些对我不起作用。他们要么在旋转设备时重新下载所有图像,要么根本不工作。

我在考虑将图像放在bytearray中,当convertView!= null时,将它们从字节数组中取出而不是重新加载。但我当然可以使用这方面的帮助。必须有我的getView工作方式。

由于

3 个答案:

答案 0 :(得分:0)

我可以看到,当您使用convertView时 - 您没有致电convertView.setImageBitmap() - 这可能是问题吗?

答案 1 :(得分:0)

最有可能发生这种情况,因为ListView会重复使用视图。

如果你将getView更改为

,我很确定它会正常工作
  if (true/*convertView == null*/) {

这样,视图将不会被重复使用 请注意,这仅用于测试潜在原因的位置 重用convertView 是一种很好的方法。

如果这证明工作正常,问题确实在你的getView else分支中,正如Jin35已经表明的那样。同样在else分支中,您应该调用imageView.setImageBitmap(someBitmap),因为您不能假设convertView参数与position-parameter匹配。

答案 2 :(得分:0)

我现在拥有以下内容:

ImageAdapter有public static ArrayList<Bitmap> bitmapArray = new ArrayList<Bitmap>();

getView是这样的:

public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;

    if (convertView == null) {
        imageView = new ImageView(mContext);
        imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(8, 8, 8, 8);

        LoadThumbs downloader = new LoadThumbs(imageView);

        downloader.execute(Loggedin.mImageIds.get(position));

    } else {
        imageView = (ImageView) convertView;
        try{
            imageView.setImageBitmap(bitmapArray.get(position+1));
        } catch (Exception e){}
    }

    return imageView;
}

然后在LoadThumbs:

protected void onPostExecute(Bitmap result) {
    if (imageViewReference != null) {
        ImageView imageView = imageViewReference.get();
        if (imageView != null) {
            ImageAdapter.bitmapArray.add(result);
            imageView.setImageBitmap(result);
        }
    }
}

这样做首先下载图像,将它们放在imageView中。同时它将它们放在Bitmap数组中。当屏幕旋转时,它使用数组中的图像而不是重新加载它们。据我了解。

它使用imageView.setImageBitmap(bitmapArray.get(position+1));(注意+1),因为由于某种原因,bitmapArray中的第二个位图(索引1)是第一个(索引0)的副本。

这现在有效。我敢打赌,这不是最好或最干净的方式,所以如果你们中的任何人对我的代码有所改进,那就让它知道吧!

修改

对于任何试图解决此问题的人。我最终得到了一个解决方案,现在100%适合我。

我首先使用空索引填充位图ArrayList:

    for (int i = 0; i < Loggedin.mImageIds.size(); i++) { 
        ImageAdapter.bitmapArray.add(null);
    }

然后我创建了一个新的Object来传递给AsyncTask而不是字符串。该对象包含url和位置整数。

public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;

    if (convertView == null) {
        imageView = new ImageView(mContext);
        imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(8, 8, 8, 8);

        LoadThumbs downloader = new LoadThumbs(imageView);

        Object[] arr = new Object[2];
        arr[0] = Loggedin.mImageIds.get(position);
        arr[1] = new Integer(position);

        downloader.execute(arr);

    } else {
        imageView = (ImageView) convertView;

        try {

            imageView.setImageBitmap(bitmapArray.get(position));
        } catch(Exception e){}

    }

    return imageView;
}

在LoadThumbs中,我有一个Object而不是字符串

public class LoadThumbs extends AsyncTask<Object, Void, Bitmap> {

然后在doInBackground方法中,我从对象中获取正确的参数。

url = (String) params[0];
position = (Integer) params[1];

onPostExecute方法中,我将图像放在数组中的正确位置:

try {
     ImageAdapter.bitmapArray.set(position, result);
} catch (Exception e) {}      

最后,getView方法中的else分支可以访问正确的位图。