我有一个将缩略图加载到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工作方式。
由于
答案 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
分支可以访问正确的位图。