我使用SimpleCursorAdapter和GridActivity(我基于ListActivity编写的扩展活动)从MediaStore加载音乐专辑,并使用AsyncTask加载每个专辑封面。
我在bindView
或getView
中尝试过此操作,如下所示:
new AsyncAlbumArtLoader(viewholder.album_art, mShowFadeAnimation).execute(aid, width, height);
班级AsyncAlbumArtLoader
:
private class AsyncAlbumArtLoader extends AsyncTask<Object, Void, Bitmap> {
boolean enable_animation = false;
private ImageView imageview;
public AsyncAlbumArtLoader(ImageView imageview, Boolean animation) {
enable_animation = animation;
this.imageview = imageview;
}
@Override
protected void onPreExecute() {
if (enable_animation) {
imageview.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(),
android.R.anim.fade_out));
imageview.setVisibility(View.INVISIBLE);
}
}
@Override
protected Bitmap doInBackground(Object... params) {
return MusicUtils.getCachedArtwork(getApplicationContext(), (Long) params[0],
(Integer) params[1], (Integer) params[2]);
}
@Override
protected void onPostExecute(Bitmap result) {
if (result != null) {
imageview.setImageBitmap(result);
} else {
imageview.setImageResource(R.drawable.albumart_mp_unknown_list);
}
if (enable_animation) {
imageview.setVisibility(View.VISIBLE);
imageview.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(),
android.R.anim.fade_in));
}
}
}
但是图像随机地在gridview项目之间移动。
您可以看到屏幕录制视频here。
已编辑通过setTag()防止此错误,并且getTag()也无效。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
mAlbumCursor.moveToPosition(position);
ViewHolder viewholder = (ViewHolder) view.getTag();
String album_name = mAlbumCursor.getString(mAlbumIndex);
if (album_name == null || MediaStore.UNKNOWN_STRING.equals(album_name)) {
viewholder.album_name.setText(R.string.unknown_album_name);
} else {
viewholder.album_name.setText(album_name);
}
String artist_name = mAlbumCursor.getString(mArtistIndex);
if (album_name == null || MediaStore.UNKNOWN_STRING.equals(album_name)) {
viewholder.artist_name.setText(R.string.unknown_artist_name);
} else {
viewholder.artist_name.setText(artist_name);
}
// We don't actually need the path to the thumbnail file,
// we just use it to see if there is album art or not
long aid = mAlbumCursor.getLong(mAlbumIdIndex);
int width = getResources().getDimensionPixelSize(R.dimen.gridview_bitmap_width);
int height = getResources().getDimensionPixelSize(R.dimen.gridview_bitmap_height);
viewholder.album_art.setTag(aid);
new AsyncAlbumArtLoader(viewholder.album_art, mShowFadeAnimation, aid, width, height).execute();
long currentalbumid = MusicUtils.getCurrentAlbumId();
if (currentalbumid == aid) {
viewholder.album_name.setCompoundDrawablesWithIntrinsicBounds(0, 0,
R.drawable.ic_indicator_nowplaying_small, 0);
} else {
viewholder.album_name.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
return view;
}
// FIXME image loaded some times incorrect
private class AsyncAlbumArtLoader extends AsyncTask<Object, Void, Bitmap> {
boolean enable_animation = false;
private ImageView imageview;
private long album_id;
private int width,height;
public AsyncAlbumArtLoader(ImageView imageview, Boolean animation, long album_id, int width, int height) {
enable_animation = animation;
this.imageview = imageview;
this.album_id = album_id;
this.width = width;
this.height = height;
}
@Override
protected void onPreExecute() {
if (imageview.getTag() == null || (Long)imageview.getTag() != album_id) {
return;
}
if (enable_animation) {
imageview.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(),
android.R.anim.fade_out));
imageview.setVisibility(View.INVISIBLE);
}
}
@Override
protected Bitmap doInBackground(Object... params) {
if (imageview.getTag() == null || (Long)imageview.getTag() != album_id) {
return null;
}
return MusicUtils.getCachedArtwork(getApplicationContext(), album_id,
width, height);
}
@Override
protected void onPostExecute(Bitmap result) {
if (imageview.getTag() == null || (Long)imageview.getTag() != album_id) {
return;
}
if (result != null) {
imageview.setImageBitmap(result);
} else {
imageview.setImageResource(R.drawable.albumart_mp_unknown_list);
}
if (enable_animation) {
imageview.setVisibility(View.VISIBLE);
imageview.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(),
android.R.anim.fade_in));
}
}
}
答案 0 :(得分:1)
问题是,AsyncTask不知道它们在哪个ImageView开始时,它们会重叠。
要防止这种情况,您需要执行以下操作:
在getView
方法中(在调用AsyncTask-Constructor之前,你需要在ImageView中设置一个Tag:myImageView.setTag(object)
。最好的选择是,如果你使用getView获取其信息的对象。在你身上case我认为它是带有Album-Information的ArrayList。让'说myImageView.setTag(myAlbumArray.get(position))
TAG必须是独一无二的
现在向AsyncTask类添加一个新的String'标记'并添加this.tag = imageview.getTag().toString()
现在最后在onPostExecute
:
if (imageview.getTag().toString().equals(tag)) {
// you got the right imageView, *your PostExecute Code* }
else {// wrong one, do nothing
}