1

ベース アダプターと LruCache を使用して、すべての連絡先画像を含むリスト ビューを実装しようとしています。しかし、画面上の長いスクロールでは、実際の画像を設定する前にすべての画像(そのビューに対応する)が表示されます。

例: 1 ページあたり 5 項目のリスト ビュー。最初の連絡先から 60 番目までスクロールした場合、リスト ビューの最初のビューでは、1,6,11,16,21..51 の画像が 55 番目の画像の前に数ミリ秒間表示されます。示されています

主なコードは

//Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = (ImageView) convertView;
if(imageView == null){
 imageView = new ImageView(getActivity());
}    
int id =  contactId[position];
final String imageKey = String.valueOf(contactId);
final Bitmap bitmap = cache.get(imageKey);
if (bitmap != null) {
  imageView.setImageBitmap(bitmap);
} else {    
  Resources res = context.getResources();
  BitmapManager bm = new BitmapManager(imageView, res, cache);
  bm.setContext(getActivity());
  bm.execute(id);
}
return imageView;
}

BitmapManager ポスト実行コード

@Override
protected void onPostExecute(Bitmap bitmap) {
    // TODO Auto-generated method stub
    try{
        if(isCancelled()){
            bitmap = null;
        }
        if(imageViewReference != null && bitmap != null){
            ImageView imageView = imageViewReference.get();
            imageView.setImageBitmap(bitmap);
            cache.put(String.valueOf(res), bitmap);
            if(imageView != null){
                imageView.setImageBitmap(bitmap);
            }

        }
    }catch(Exception e){

    }
    super.onPostExecute(bitmap);
}

この問題を解決する方法。ありがとう

4

1 に答える 1

1

下にスクロールすると、表示される新しいリスト位置にビューが再利用されます。getView が呼び出されるたびに新しい BitmapManager タスクを開始するため、タスクが並んでイメージの更新を待機します。それぞれがビットマップのロードを完了すると、それを順番に ImageView に入れます。これが表示されているものです。

ビューからスクロールされた後にビットマップを使用しないように ImageView への参照を使用しようとしていたようですが、うまくいかなかった理由は、アダプターが ImageViews をリサイクルしているため、参照は有効なままです。実際には ImageView が別のリスト項目に使用されていますが。

これを解決するにはさまざまな方法がありますが、思いつく最も簡単な方法は、ImageView 自体ではなく、リスト インデックスを使用して BitmapManager を構築することです。次に getView で、どのビューがどの位置で使用されているかのマップを保持できます。BitmapManager が終了したら、キャッシュにロードしたばかりの位置に現在の ImageView があるかどうかを確認します。そうでない場合は、何もしません。

ここに私が話していることを示すいくつかのコードがあります。試していないので、間違っていたらすみません。

//Adapter
private SparseArray<ImageView> ivMap = new SparseArray<ImageView>();
public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView = (ImageView) convertView;
    if(imageView == null){
      imageView = new ImageView(getActivity());
    } else {
      // If recycled, remove the ImageView's previous position from map
      int oldPosition = ivMap.indexOfValue(imageView);
      if (oldPosition >= 0) {
        ivMap.remove(oldPosition);
      }
    }
    // Keep track of which view is representing this position
    ivMap.put(position, imageView);

    int id =  contactId[position];
    final String imageKey = String.valueOf(contactId);
    final Bitmap bitmap = cache.get(imageKey);
    if (bitmap != null) {
      imageView.setImageBitmap(bitmap);
    } else {    
      Resources res = context.getResources();
      BitmapManager bm = new BitmapManager(ivMap, position, res, cache);
      bm.setContext(getActivity());
      bm.execute(id);
    }
    return imageView;
}

//BitmapManager
@Override
protected void onPostExecute(Bitmap bitmap) {
    // TODO Auto-generated method stub
    try{
        if(isCancelled()){
            bitmap = null;
        }
        if(bitmap != null){
            cache.put(String.valueOf(res), bitmap);
            ImageView imageView = ivMap.get(position);
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }catch(Exception e){

    }
    super.onPostExecute(bitmap);
}
于 2014-12-12T03:54:36.963 に答える