Dak*_*ksh 10 android listview thumbnails recycle android-asynctask
我一直在尝试使用缩略图来处理ListView中的图像文件的AsyncTask.我一直遇到行回收的常见问题,因此滚动缩略图被分配给错误的行.我已经尝试将标签添加到ImageView,然后在AsyncTask中的onPostExecute()中确认标签,但是在我的尝试中却没有成功.有人请帮忙!
自定义适配器如下:
public class MySimpleAdapter extends SimpleAdapter {
public MySimpleAdapter(Context context,
List<? extends Map<String, ?>> data, int resource,
String[] from, int[] to) {
super(context, data, resource, from, to);
// TODO Auto-generated constructor stub
}
public View getView(int position, View convertView, ViewGroup parent) {
final View v = super.getView(position, convertView, parent);
thumbnail = (ImageView) v.findViewById(R.id.thumbnail);
checker = (CheckBox) v.findViewById(R.id.checkBox);
filenametext = (TextView) v.findViewById(R.id.text1);
String pathtoimage = startLocation.concat("/"
+ filenametext.getText().toString());
desctext = (TextView) v.findViewById(R.id.text2);
String temp = desctext.getText().toString();
if (temp.equals("Directory") == true) {
checker.setEnabled(false);
switch (theme) {
case 0:
thumbnail.setImageResource(R.drawable.folder_light);
break;
case 1:
thumbnail.setImageResource(R.drawable.folder_dark);
break;
}
} else {
checker.setEnabled(true);
if (filenametext.getText().toString().endsWith(".jpg")
|| filenametext.getText().toString().endsWith(".png")
|| filenametext.getText().toString().endsWith(".bmp")) {
Boolean hashmapfound = false;
for (HashMap.Entry<String, Bitmap> entry : thumbnaillist
.entrySet()) {
String key = entry.getKey();
if (key.equals(filenametext.getText().toString())) {
Log.d(TAG, "HashMapKey Found!");
thumbnail.setImageBitmap(entry.getValue());
hashmapfound = true;
}
}
if (!hashmapfound) {
Log.d(TAG, "NO HashMapKey Found! Adding to HashMap!");
switch (theme) {
case 0:
thumbnail
.setImageResource(R.drawable.unknown_image_light);
break;
case 1:
thumbnail
.setImageResource(R.drawable.unknown_image_dark);
break;
}
thumbnail.setTag((filenametext.getText().toString()));
new GetBitMaps(thumbnail).execute(pathtoimage,
filenametext.getText().toString());
}
} else {
switch (theme) {
case 0:
thumbnail.setImageResource(R.drawable.file_light);
break;
case 1:
thumbnail.setImageResource(R.drawable.file_dark);
break;
}
}
}
return v;
}
}
Run Code Online (Sandbox Code Playgroud)
AsyncTask如下:
class GetBitMaps extends AsyncTask<String, Void, Bitmap> {
private ImageView thumbnail;
private String imageName;
public GetBitMaps(ImageView thumb) {
// TODO Auto-generated constructor stub
thumbnail = thumb;
}
@Override
protected Bitmap doInBackground(String... pathtoimage) {
Bitmap bmp = createThumbnail(pathtoimage[0]);
thumbnaillist.put(pathtoimage[1], bmp);
imageName = pathtoimage[1];
return bmp;
}
@Override
protected void onPostExecute(Bitmap bmp) {
if (((String) thumbnail.getTag()).equals(imageName)) {
thumbnail.setImageBitmap(bmp);
}
}
private Bitmap createThumbnail(String filepath) {
Bitmap bmp = BitmapFactory.decodeFile(filepath);
int w = bmp.getWidth();
int h = bmp.getHeight();
if (w > h) {
w = 80;
h = 40;
} else if (w < h) {
w = 40;
h = 80;
}
bmp = Bitmap.createScaledBitmap(bmp, w, h, true);
return bmp;
}
}
Run Code Online (Sandbox Code Playgroud)
我仍然无法弄清楚还有什么可以让缩略图显示在滚动的正确行上.
请注意:滚动远离受影响的行并向下滚动后,一切正常,但滚动问题不会消失!
Jef*_*rod 20
来自这篇博文:
您要做的是在一个单独的线程中异步运行所有每行IO或任何繁重的CPU绑定例程.这里的诀窍是这样做,仍然符合ListView的回收行为.例如,如果运行AsyncTask以在适配器的getView()中加载配置文件图片,则在AsyncTask完成之前,您正在加载图像的视图可能会被回收到另一个位置.因此,您需要一种机制来了解一旦完成异步操作后视图是否还没有被回收.
实现此目的的一种简单方法是将一些信息附加到视图,以识别与其关联的行.然后,您可以在异步操作完成时检查视图的目标行是否仍然相同.有很多方法可以实现这一目标.这里只是一个简单的草图,你可以做到这一点:
public View getView(int position, View convertView,
ViewGroup parent) {
ViewHolder holder;
...
holder.position = position;
new ThumbnailTask(position, holder)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
return convertView;
}
private static class ThumbnailTask extends AsyncTask {
private int mPosition;
private ViewHolder mHolder;
public ThumbnailTask(int position, ViewHolder holder) {
mPosition = position;
mHolder = holder;
}
@Override
protected Cursor doInBackground(Void... arg0) {
// Download bitmap here
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (mHolder.position == mPosition) {
mHolder.thumbnail.setImageBitmap(bitmap);
}
}
}
private static class ViewHolder {
public ImageView thumbnail;
public int position;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13303 次 |
| 最近记录: |