我正在查询SQLite数据库并将数据放入列表视图。数据库行之一包含图像Url字段(也可以是Uri)。
图像将按原样加载,但是一旦我滚动列表,所有图像就会开始闪烁,其中一些正在更改位置或显示在不同的位置。
我已经知道这种现象正在发生,因为列表视图正在重复使用滚动中的行,但是我不知道如何解决此问题。我也不能在该项目中使用像Picasso这样的外部库。
这是我的适配器代码:
public class FilmsListCustomAdapter extends CursorAdapter {
private LayoutInflater cursorInflater;
public FilmsListCustomAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
cursorInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView filmTitle = (TextView) view.findViewById(R.id.filmListTitle);
TextView filmScore = (TextView) view.findViewById(R.id.filmListScore);
ImageView filmImage = (ImageView)view.findViewById(R.id.filmListPoster);
ImageView filmSeen = (ImageView)view.findViewById(R.id.filmListSeen);
String title = cursor.getString( cursor.getColumnIndex("title") );
String score = cursor.getString(cursor.getColumnIndex("score"));
String url = cursor.getString( cursor.getColumnIndex("url") );
int seen = cursor.getInt( cursor.getColumnIndex("seen") );
if(Patterns.WEB_URL.matcher(url).matches()){
LoadImage loadImage = new LoadImage(context,filmImage);
loadImage.execute(url);
}
else{
Bitmap bmp = BitmapFactory.decodeFile(url);
CamImage camImage = new CamImage(context,Uri.parse(url));
Bitmap rotetedIm = camImage.rotateCamImage(bmp,url);
if(rotetedIm!=null){filmImage.setImageBitmap(Bitmap.createScaledBitmap(rotetedIm, 850, rotetedIm.getHeight(), false));}
else{filmImage.setImageResource(R.drawable.no_poster);}
}
GlobalMethods methods = new GlobalMethods(context);
filmTitle.setTypeface(methods.getWalkFont());
filmTitle.setText(title);
filmScore.setText(score);
if(seen==1){filmSeen.setImageResource(R.drawable.eye);}
else{filmSeen.setImageResource(0);}
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
return cursorInflater.inflate(R.layout.film_row, viewGroup, false);
}
}
可能是这样的:
您会获得图片的网络网址,并排队将其AsyncTask
下载到ImageView
您滚动并ImageView
回收
这次ImageView
获取本地URL,因此您可以立即执行此操作
先前排队AsyncTask
的图像会完成并在您刚刚放入的图像上加载现在不相关的图像
清除此错误的关键是确保在ImageView
回收任务后立即取消该任务。一种方法是AsyncTask
在的标记中放置对的引用ImageView
。回收后ImageView
,您可以检查标签并查看是否有正在进行的任务,并在开始新任务之前将其取消。
您应该在Android Developers Blog上查看这篇文章,它将进一步说明该问题及其解决方法:
我认为这篇文章是在将AsyncTask
s更改为在并行线程中运行时写的,因为它们谈论的任务是无序完成的。从那以后,它们已恢复为串行执行,因此我认为该部分不再适用,但是概念很相似,因为您立即加载本地映像的操作就像是乱序执行的任务。
我会考虑另外两件事:
进入时getView
,始终imageView.setImageBitmap(null)
首先调用以清除回收的任何残留图像ImageView
。我喜欢用ImageView
一个非常中性的灰色位图来表示“图像加载”状态。
使用AsyncTask
解码本地文件以及检索网络文件。我敢打赌,当您执行此操作时,列表滚动看起来会更加流畅。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句