在我的应用程序中,有一个ListView
使用自定义CursorAdapter
将数据加载到其中的应用程序,它基本上是一个ImageView
和一个TextView
。我正在加载图像AsyncTask
,现在的问题是,最初所有图像都分配给正确的文本,但是当我快速上下滚动时,它会为每个文本绑定随机图像。由于我使用的是 CursorAdapter ,所以我不能ViewHolder
在这里使用,那么我该怎么做才能消除这个问题呢?
这是我的示例代码:
public class MyAdapter extends CursorAdapter {
private LayoutInflater mLayoutInflater;
@SuppressWarnings("unused")
private Context mContext;
public MyAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
mContext = context;
mLayoutInflater = LayoutInflater.from(context);
}
public void bindView(View view, Context context, Cursor cursor) {
String title = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.TITLE));
String album_id = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
TextView text = (TextView)view.findViewById(R.id.txtTitle);
text.setText(title);
Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
Uri uri = ContentUris.withAppendedId(sArtworkUri, Integer.valueOf(album_id));
new MyImageLoader(context,view).execute(uri);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return mLayoutInflater.inflate(R.layout.row, parent, false);
}
private class MyImageLoader extends AsyncTask<Uri, Void, Bitmap>{
Context context;
View view;
MyImageLoader(Context context,View view){
this.context = context;
this.view = view;
}
@Override
protected Bitmap doInBackground(Uri... uri) {
ContentResolver res = context.getContentResolver();
InputStream in = null;
try {
in = res.openInputStream(uri[0]);
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap artwork = BitmapFactory.decodeStream(in);
return artwork;
}
protected void onPostExecute(Bitmap bmp){
ImageView iv = (ImageView)view.findViewById(R.id.imgIcon);
if(bmp!=null)
//iv.setImageBitmap(bmp);
iv.setImageBitmap(Bitmap.createScaledBitmap(bmp, 100, 100, false));
}
}
}
更新: 我应用了 setTag 方法,现在洗牌变少了,但是当我快速滚动时,旧图像会持续一秒钟,直到加载正确的图像。这是新代码:
public void bindView(View view, Context context, Cursor cursor) {
String title = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.TITLE));
String album_id = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
ImageView iv = (ImageView)view.findViewById(R.id.imgIcon);
TextView text = (TextView)view.findViewById(R.id.txtTitle);
text.setText(title);
Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
Uri uri = ContentUris.withAppendedId(sArtworkUri, Integer.valueOf(album_id));
// *****TAG SET*****
iv.setTag(uri);
//***PASSING BOTH URI AND IMAGEVIEW TO CONSTRUCTOR***
new MyImageLoader(context,view,iv,uri).execute(uri);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = mLayoutInflater.inflate(R.layout.row, parent, false);
//v.setTag(R.id.imgIcon, v.findViewById(R.id.imgIcon));
return v;
}
private class MyImageLoader extends AsyncTask<Object, Void, Bitmap>{
Context context;
View v;
ImageView iv;
Uri u;
MyImageLoader(Context context,View v,ImageView iv,Uri u){
this.context = context;
this.v = v;
this.iv = iv;
this.u = u;
}
@Override
protected synchronized Bitmap doInBackground(Object... param) {
ContentResolver res = context.getContentResolver();
InputStream in = null;
try {
Uri uri= (Uri)param[0];
in = res.openInputStream(uri);
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap artwork = BitmapFactory.decodeStream(in);
return artwork;
}
protected void onPostExecute(Bitmap bmp){
if(bmp!=null)
{ ImageView iv = (ImageView)v.findViewById(R.id.imgIcon);
if(iv.getTag().toString().equals(u.toString()))
iv.setImageBitmap(Bitmap.createScaledBitmap(bmp, 100, 100, false));
}
}
}
更新:在调用后台任务之前设置占位符图像会更好。