AndroidはListViewに画像を表示する(錯乱点滅の問題を繰り返す)


AndroidはListViewに画像を表示する(錯乱点滅の問題を繰り返す)
1、原因分析
ListView itemキャッシュメカニズム:
パフォーマンスを向上させるために、ListViewは行item(対応する行)をキャッシュします.
ListViewは、adapterのgetView関数によって各行のitemを取得する.
スライド中
a.ある行のitemが画面から滑り出した場合、そのitemがキャッシュ内にない場合、putはキャッシュに入り、そうでない場合、キャッシュを更新する.
b.画面にスライドする行itemを取得する前に、キャッシュに使用可能なitemがあるかどうかを判断し、ある場合はconvertViewパラメータとしてadapterのgetViewに渡します.
これにより,次のようなgetView書き方がキャッシュを活用してListViewの性能を大幅に向上させることができる.数万行itemでも最大inflateの回数はnで、
nは、一画面で最大ListView行itemを表示する個数である.@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 ( ) ;       } }
これにより、パフォーマンスが向上しますが、他の問題も発生します.
a.行itemピクチャ表示繰返し
この表示重複とは、現在の行itemが以前の行itemのピクチャを表示していることを意味します.
例えばListViewが2行目にスライドすると、あるピクチャが非同期でロードされるが、ロードが遅く、ロード中にlistViewが14行目にスライドし、スライド中にそのピクチャのロードが終了する、
2行目は画面内にありません.上記のキャッシュ原理に基づいて、2行目のviewが14行目に多重化される可能性があります.これにより、14行目に2行目に属する画像が表示されます.
表示が重複します.
b.行item画像表示エラー
この表示エラーとは、ある行itemがその行itemに属さない画像を表示していることを意味します.
例えばListViewが2行目にスライドすると、あるピクチャは非同期でロードされるが、ロードが遅く、ロード中にlistViewが14行目にスライドし、2行目が画面内に存在しなくなり、上述したキャッシュ原理により、2行目のviewが14行目に多重化される可能性があり、14行目に2行目のViewが表示されると、その時点で前のピクチャのロードが終了し、14行目に表示され、エラーが発生する.
c.行itemピクチャ表示点滅
上のbの場合、14行目の画像はすぐにロードが完了するので、14行目に2行目の画像が先に表示されているのを見て、すぐに自分の画像が表示されて上書きされて点滅が乱れています.
2、解決方法
以上の解析から,錯乱の原因は非同期ロードとオブジェクトの多重化によるものであることが分かったが,getViewのたびにオブジェクトに識別を与えることができ,非同期ロードが完了するたびに現在の行itemの識別と一致するかどうかを比較し,一致すると表示され,そうでなければ処理を行わない.
andbaseの実装コード:/**       * , .       * : ,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の紹介:http://blog.csdn.net/menglele1314/article/details/46422409
ダウンロード:http://download.csdn.net/detail/menglele1314/8786989