Android Display picture in ListView (repeat confusion flashing problem)
1. Cause analysis
ListView Item Cache mechanism:
To make the performance better, the ListView caches the line item (the view that corresponds to a row).
The ListView obtains the item for each line through the GetView function of the adapter.
During the sliding process
A. If a line item has been slid out of the screen, if the item is not in the cache, put in the cache, otherwise update the cache;
B. Gets the line item that slides into the screen before it determines if there is an item available in the cache, and if so, the getview that is passed to adapter for the Convertview parameter.
This way, the GetView can be used to make full use of the cache to greatly improve the performance of the ListView. Even if tens of thousands of lines of item, the maximum number of inflate is N,
n Displays the maximum number of ListView rows item for a screen.
@Override
public
View getView (
int
position , View convertView , ViewGroup parent ) {
ViewHolder holder ;
if
( convertView ==
null
) {
convertView = inflater . inflate ( R . layout . list_item ,
null
) ;
holder =
new
ViewHolder ( ) ;
……
convertView . setTag ( holder ) ;
}
else
{
holder = ( ViewHolder ) convertView . getTag ( ) ;
}
}
This improves performance, but it also creates additional problems:
A. The line item picture displays duplicates
This display repetition means that the current line item shows a picture of the previous line item.
For example, the ListView slides to the 2nd row to load a picture asynchronously, but the load is slow, the ListView has slid to line 14th during the loading process, and the picture is loaded at the end of the slide.
Line 2nd is no longer in the screen, according to the caching principle described above, the 2nd line of view may be reused in line 14th, so we see that the 14th line shows the image that should belong to the 2nd line,
Causes the display to repeat.
B. Line item picture shows confusion
This display disorder refers to a line item that shows a picture that does not belong to the line item.
For example, the ListView slides to the 2nd line to load a picture asynchronously, but the load is slow, the ListView has been sliding to the 14th row, the 2nd line is no longer on the screen, according to the caching principle described above, the 2nd line of view may be reused by the 14th line, Line 14th shows the view of line 2nd, when the previous picture is loaded, it will appear in line 14th, causing confusion.
C. Line item picture Display flashes
In the case of the above B, the 14th line of the picture again quickly loaded the end, so we see the 14th line first shows the image of the 2nd line, and immediately show their own image to cover the flicker caused by confusion.
2. Solution
Through the above analysis we know that the cause of the disorder is the asynchronous loading and the object is reused, if each time GetView can give an identity to the object, when the asynchronous loading is done to compare the identity with the current row of the identity of the item is consistent, the same is displayed, otherwise do not do processing.
AndbaseThe implementation code in:
/**
* 显示这个图片,解决了列表问题.
* 列表问题:滑动过程中,getView的imageView会重复利用,导致图片会串位
* @param imageView 显得的View
* @param url the url
* @return
*/
public
void
display(
final
ImageView imageView,String url) {
if
(AbStrUtil.isEmpty(url)){
if
(noImage !=
null
){
if
(loadingView !=
null
){
loadingView.setVisibility(View.INVISIBLE);
imageView.setVisibility(View.VISIBLE);
}
imageView.setImageDrawable(noImage);
}
return
;
}
//设置下载项
final
AbImageDownloadItem item =
new
AbImageDownloadItem();
//设置显示的大小
item.width = width;
item.height = height;
//设置为缩放
item.type = type;
item.imageUrl = url;
final
String cacheKey = AbImageCache
.getCacheKey(item.imageUrl, item.width, item.height, item.type);
item.bitmap = AbImageCache.getBitmapFromCache(cacheKey);
//if(D) Log.d(TAG, "缓存中获取的"+cacheKey+":"+item.bitmap);
//设置标记
imageView.setTag(url);
if
(item.bitmap ==
null
){
//先显示加载中
if
(loadingView!=
null
){
loadingView.setVisibility(View.VISIBLE);
imageView.setVisibility(View.INVISIBLE);
}
else
if
(loadingImage !=
null
){
imageView.setImageDrawable(loadingImage);
}
//下载完成后更新界面
item.setListener(
new
AbImageDownloadListener() {
@Override
public
void
update(Bitmap bitmap, String imageUrl) {
//未设置加载中的图片,并且设置了隐藏的View
if
(loadingView !=
null
&& imageUrl.equals(imageView.getTag())){
loadingView.setVisibility(View.INVISIBLE);
imageView.setVisibility(View.VISIBLE);
}
//要判断这个imageView的url有变化,如果没有变化才set,
//有变化就取消,解决列表的重复利用View的问题
if
(bitmap!=
null
&& imageUrl.equals(imageView.getTag())){
if
(D) Log.d(TAG,
"图片下载,设置:"
+imageUrl);
imageView.setImageBitmap(bitmap);
}
else
{
if
(errorImage !=
null
&& imageUrl.equals(imageView.getTag())){
imageView.setImageDrawable(errorImage);
}
}
}
});
if
(D) Log.d(TAG,
"图片下载,执行:"
+url);
mAbImageDownloadPool.execute(item);
}
else
{
if
(loadingView !=
null
){
loadingView.setVisibility(View.INVISIBLE);
imageView.setVisibility(View.VISIBLE);
}
imageView.setImageBitmap(item.bitmap);
}
}
andbase Introduction: http://blog.csdn.net/menglele1314/article/details/46422409
Download: http://download.csdn.net/detail/menglele1314/8786989
Android Display picture in ListView (repeat confusion flashing problem)