I've been evaluating NOSTRA's Universal-Image-Loader library to asynchronously download images and show them in ListView. So far it works fine except for one problem.
Sometimes Bitmaps from memory cache get attached to wrong ImageViews
when the list is being scrolled. After scrolling is stopped, correct images are attached. This situation is quite rare and I couldn't find a 100% way to reproduce it. I shot a video last time it happened.
Here is the ArticleAdapter
code, both the UIL config and the bindView()
method can be found there.
public class ArticleAdapter extends CursorAdapter {
private LayoutInflater inflater;
private ViewHolder holder;
public ArticleAdapter(Context context, Cursor cursor, boolean autoRequery) {
super(context, cursor, autoRequery);
imageLoader = ImageLoader.getInstance();
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.download_progress_thumb)
.cacheInMemory()
.cacheOnDisc()
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
.build();
ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(context)
.threadPriority(Thread.NORM_PRIORITY - 2)
.threadPoolSize(4)
.discCache(new UnlimitedDiscCache(Utils.getCacheDirectory(context)))
.defaultDisplayImageOptions(options)
.build();
imageLoader.init(configuration);
titleIndex = cursor.getColumnIndex(Articles.TITLE);
descriptionIndex = cursor.getColumnIndex(Articles.DESCRIPTION);
isUnreadIndex = cursor.getColumnIndex(Articles.IS_UNREAD);
isNewIndex = cursor.getColumnIndex(Articles.IS_NEW);
urlIndex = cursor.getColumnIndex(Articles.URL);
hostIndex = cursor.getColumnIndex(Articles.HOST);
timeIndex = cursor.getColumnIndex(Articles.PUBLISH_TIME);
bkgUnreadArticle = context.getResources().getColor(R.color.list_bkg_unread_article);
bkgReadArticle = context.getResources().getColor(R.color.list_bkg_read_article);
textUnreadTitle = context.getResources().getColor(R.color.list_text_unread_title);
textReadTitle = context.getResources().getColor(R.color.list_text_read_title);
inflater = LayoutInflater.from(context);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
String date = Utils.format(cursor.getLong(timeIndex), Utils.DATE);
holder = (ViewHolder) view.getTag();
holder.titleView.setText(cursor.getString(titleIndex));
holder.descriptionView.setText(date);
int isNew = cursor.getInt(isNewIndex);
if (isNew == 1)
holder.isNewView.setVisibility(View.VISIBLE);
else
holder.isNewView.setVisibility(View.INVISIBLE);
int isUnread = cursor.getInt(isUnreadIndex);
if (isUnread == 1){
holder.titleView.setTextColor(textUnreadTitle);
holder.rowLayout.setBackgroundColor(bkgUnreadArticle);
} else {
holder.titleView.setTextColor(textReadTitle);
holder.rowLayout.setBackgroundColor(bkgReadArticle);
}
String url = cursor.getString(urlIndex);
String host = cursor.getString(hostIndex);
if (host.equalsIgnoreCase(Consts.HOST_LENTA) || host.equalsIgnoreCase(Consts.HOST_REALTY)) {
holder.thumbView.setVisibility(View.VISIBLE);
imageLoader.displayImage(Utils.makeImageUrl(url, Utils.THUMBNAIL), holder.thumbView);
} else
holder.thumbView.setVisibility(View.GONE);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = inflater.inflate(R.layout.articlelist_item, null);
ViewHolder holder = new ViewHolder();
holder.titleView = (TextView) v.findViewById(R.id.list_title);
holder.descriptionView = (TextView) v.findViewById(R.id.list_description);
holder.thumbView = (ImageView) v.findViewById(R.id.list_thumb);
holder.isNewView = (TextView) v.findViewById(R.id.list_read_unread);
holder.rowLayout = (LinearLayout) v.findViewById(R.id.list_row);
v.setTag(holder);
return v;
}
}
I would really appreciate any help on this matter.
PauseOnScrollListener
? – Amblygonite