2

このような質問をいくつか見ましたが、少し異なる問題が発生しているようです。だからここで誰かに聞いてみようと思いました。

textviewとimageviewを備えたカスタムリストビューがあります。非同期タスクを使用して画像を読み込んでから、postexecuteメソッドで画像をimageviewに設定しています。画像は正常に読み込まれていますが、一部の画像が他の画像に置き換えられています。ただし、すべての画像の読み込みが完了すると、各画像ビューに適切な画像が表示されます。しかし、なぜこの問題が発生するのか理解できないようです。

これが私のアダプターと非同期タスククラスです。ありとあらゆる助けをいただければ幸いです。

編集私は今タグを追加しています(タグはそれぞれのtextviewのimageviewsに入るテキストです)そして私の投稿の実行で私はタグがtextviewからのテキストと等しいかどうかをチェックしています。私はまだ以前と同じ問題を抱えています。

これが私のAdapterクラスです:

public class CustomListAdapter extends ArrayAdapter<CustomList> {

    Context context;
    int layoutResourceId;
    LinkedList<CustomList> data = null;
    LinkedList<String> title_list = new LinkedList();

    LoadImage l;
    CustomList cl;
    ProgressBar pb;
    HashMap <String, Bitmap> bitmap = new HashMap<String, Bitmap>();







    public CustomListAdapter(Context context, int layoutResourceId, LinkedList<CustomList> data, LinkedList<Bitmap> bitmap_list) {
        super(context, layoutResourceId, data);
        // TODO Auto-generated constructor stub

        this.context = context;
        this.layoutResourceId = layoutResourceId;
        this.data = data;

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        View row = convertView;
        CustomListHolder holder = null;




        if(row == null){
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);
            holder = new CustomListHolder();

            holder.text = (TextView)row.findViewById(R.id.txtTitle);
            holder.thumbnail = (ImageView)row.findViewById(R.id.imgIcon);
            holder.pb = (ProgressBar)row.findViewById(R.id.progressBar1);

            row.setTag(R.id.id0, holder);


            cl = data.get(position);
            holder.text.setText(cl.title);
            holder.thumbnail.setImageResource(R.drawable.icon);
            holder.pb.setVisibility(View.VISIBLE);


            row.setTag(R.id.id1,new String(cl.title));
            LoadImage li = new LoadImage(context, holder.thumbnail, cl.icon,cl.title, bitmap,holder.pb,row);
            li.execute(cl.icon);        

        }

        else{
            Log.e("Row not null","Inside");
            holder = (CustomListHolder)row.getTag(R.id.id0);
            //row.getK
            cl = data.get(position);        
            holder.text.setText(cl.title);
            holder.thumbnail.setImageResource(R.drawable.icon);
            holder.pb.setVisibility(View.VISIBLE);
            if((Bitmap) bitmap.get(cl.title) == null){
                row.setTag(R.id.id1,new String(cl.title));
              LoadImage li = new LoadImage(context, holder.thumbnail, cl.icon,cl.title, bitmap,holder.pb,row);
                li.execute(cl.icon); 


            }
            else {
                holder.thumbnail.setImageBitmap((Bitmap) bitmap.get(cl.title));
                holder.pb.setVisibility(View.GONE);
            }



        }   



        return row;


    }

    static class CustomListHolder
    {
        ImageView thumbnail;
        TextView text;
        ProgressBar pb;
    }


}

これが私の非同期タスククラスです:

パブリッククラスLoadImageはAsyncTaskを拡張します{

Context callingContext = null;
ImageView view;
String bits;
public  ProgressBar pb;
HashMap<String, Bitmap> bitmap; 
String url;
String text;
View row;



public LoadImage(Context c, ImageView view, String bits, String text, HashMap<String, Bitmap> bitmap, ProgressBar pb, View row){

    this.view = view;
    this.bits = bits; // url for image
    this.callingContext = c;
    this.bitmap = bitmap; //hashmap
    this.text = text;// title text
    this.pb = pb;
    this.row = row;

}



public Bitmap getBitmap(String data){

    Bitmap bitmap;
    BitmapFactory.Options bmOptions;
    bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    Log.e("getBitmap",text);

    try {
        bitmap=null;
        InputStream is=new URL(data).openStream();
        BitmapFactory.decodeStream(is, null, bmOptions);
        is.close();
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = 10;
        is = new URL(data).openStream();
        bitmap = BitmapFactory.decodeStream(is, null, o2);

        bitmap = Bitmap.createScaledBitmap(bitmap, 60, 60, true);
        is.close();
        this.bitmap.put(text,bitmap);
        return bitmap;
    } catch (Exception ex){
        Log.e("Debug", ex.getMessage());
       return null;
    }

}


@Override
protected Bitmap doInBackground(String... arg0) {
    // TODO Auto-generated method stub
    Log.e("do In Bg",text);
    Bitmap b = null;    

    if((Bitmap)bitmap.get(text) == null)
      b = getBitmap(bits);
    else 
      b =(Bitmap)bitmap.get(text);

        return b;  
}



@Override
protected void onPostExecute(Bitmap result) {
    // TODO Auto-generated method stub
    super.onPostExecute(result);
        if(row.getTag(R.id.id1).equals(text)){
            view.setImageBitmap((Bitmap)bitmap.get(text));
            pb.setVisibility(View.GONE);
        }




}   

}

CustomListは、2つの文字列アイコンとタイトルを持つクラスです。アイコンは画像のURLで、タイトルはテキストビューのテキストです。

4

2 に答える 2

4

@Krylezが同じことを言っていたと確信しています。ListViewでは、行がリサイクルされます。これは、covertViewが提供するものであり、row==nullチェックを実行します。画面に一度に10行が表示される場合は、メモリに約11〜12行ある可能性があります。スクロールして行が表示されなくなると、その行はメモリに保持され、古いものとともに返され、再入力できます。

セル1があるとします...ビットマップ1を要求しました。次に、ユーザーがそれをスクロールしてビューから外し、ビットマップ12としてリサイクルします。オブジェクト参照がそのまま残っているため、ビットマップ1のタスクが完了し、描画されます。破壊されました)。したがって、間違った画像が表示されるというこの効果が得られます。

iOSプロジェクトで簡単な修正を使用しました。オブジェクトタグを使用します。説明させてください:

LoadImageタスクを起動するときは、ビットマップとその位置の関係を識別できる一意のIDで行にタグを付けます...

row.setTag(new Integer(ID_THAT_IDENTIFIES_ROW_AND_BITMAP_RELATIONSHIP))

非同期タスクでonPostExecute()を実行するときは、この識別子が変更されているかどうかを確認してください。現在のビットマップが一致しなくなった場合は、データの入力を待機している別のタスクがある可能性があるため、何もしないでください。

お役に立てば幸いです。

于 2012-07-27T00:08:20.373 に答える
0

この場合の私の意見は、常に新しい行を作成することです。

LayoutInflater inflater = ((Activity)context).getLayoutInflater(); 
row = inflater.inflate(layoutResourceId, parent, false);

ホルダーを使用する必要はありません(スムーズには良いようですが)。それを試してみてください。

ありがとう。

于 2015-09-10T05:09:31.600 に答える