2

ListActivity に拡張された BaseAdapter があります。

private static class RequestAdapter extends BaseAdapter {

そして、それに定義されたいくつかのハンドラーとランナブル

// Need handler for callbacks to the UI thread
    final Handler mHandler = new Handler();

    // Create runnable for posting
    final Runnable mUpdateResults = new Runnable() {
        public void run() {
            loadAvatar();
        }
    };

    protected static void loadAvatar() {
        // TODO Auto-generated method stub
        //ava.setImageBitmap(getImageBitmap("URL"+pic));
        buddyIcon.setImageBitmap(avatar);
    }

アダプターの getView 関数では、次のようなビューを取得しています。

if (convertView == null) {
            convertView = mInflater.inflate(R.layout.messageitem, null);

            // Creates a ViewHolder and store references to the two children views
            // we want to bind data to.
            holder = new ViewHolder();
            holder.username = (TextView) convertView.findViewById(R.id.username);
            holder.date = (TextView) convertView.findViewById(R.id.dateValue);
            holder.time = (TextView) convertView.findViewById(R.id.timeValue);
            holder.notType = (TextView) convertView.findViewById(R.id.notType);
            holder.newMsg = (ImageView) convertView.findViewById(R.id.newMsg);
            holder.realUsername = (TextView) convertView.findViewById(R.id.realUsername);
            holder.replied = (ImageView) convertView.findViewById(R.id.replied);
            holder.msgID = (TextView) convertView.findViewById(R.id.msgID_fr);
            holder.avatar = (ImageView) convertView.findViewById(R.id.buddyIcon);
            holder.msgPreview = (TextView) convertView.findViewById(R.id.msgPreview);


            convertView.setTag(holder);
        } else {
            // Get the ViewHolder back to get fast access to the TextView
            // and the ImageView.
            holder = (ViewHolder) convertView.getTag();
        }

画像はこのようにロードされています:

Thread sepThread = new Thread() {
                    public void run() {
                        String ava;
                        ava = request[8].replace(".", "_micro.");
                        Log.e("ava thread",ava+", username: "+request[0]);
                        avatar = getImageBitmap(URL+ava);
                        buddyIcon = holder.avatar;
                        mHandler.post(mUpdateResults);
                        //holder.avatar.setImageBitmap(getImageBitmap(URL+ava));
                    }
                };
                sepThread.start();

今、私が抱えている問題は、同じ画像を表示する必要があるアイテムがさらにある場合、それらの画像のすべてが表示されないことです。リストを上下にスクロールすると、すべての項目が埋まってしまう可能性があります。

コメント アウトされた行 (holder.avatar.setImageBitmap...) を試したところ、「ビューを作成したスレッドのみが要求できる...」というメッセージが表示され、アプリが強制終了することがあります。しかし、たまにしか。

どうすればこれを修正できますか?いずれかのオプション。

4

3 に答える 3

1

したがって、別のスレッドでビューに画像を追加しようとしないでください。私のアドバイスは、次のような AsyncTask を使用することです。

class GetImageTask extends AsyncTask<String, int[], Bitmap> {

    @Override
    protected Bitmap doInBackground(String... params) {
      Bitmap bitmap = null;

      // Get your image bitmap here

      return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap bitmapResult) {
      super.onPostExecute(bitmapResult);
      // Add your image to your view
      holder.avatar.setImageBitmap(bitmapResult);
    }
}

次のように AsyncTask を呼び出します。

new GetImageTask().execute(param1, param2, etc);

AsyncTask の詳細については、http://developer.android.com/reference/android/os/AsyncTask.html をご覧ください

于 2010-06-02T11:52:31.640 に答える
1

getView が呼び出されると、アバターの ImageView が取得されます。このインスタンスを sepThread に渡し、sepThread はこのインスタンスを mUpdateResults に渡す必要があります。このようにして、ビットマップはダウンロードされた ImageView に正確に表示されます。そうしないと、不正な budddyIcon インスタンスにビットマップが表示されます。スレッドはしばらくの間画像をダウンロードしていましたが、準備ができたら、別の getView が既に呼び出されているため、budddyIcon が別の ImageView を参照しています。

次のようになります。

public View getView(...){
  //skip
  (new SepThread(holder.avatar)).start();
}

public class SepThread extends Thread() {
    ImageView imageView;
    public SepThread(ImageVIew iv){
      imageView=iv;
    }
    public void run() {
        //skip
        Bitmap avatar = getImageBitmap(URL+ava);
        mHandler.post(new UpdateResults(imageView, avatar));
    }
};

class UpdateResults extends Runnable() {
  ImageView imageView;
  Bitmap bitmap;
  public UpdateResults(ImageView iv, Bitmap b){
    imageView=iv;
    bitmap=b;
  }
  public void run() {
      loadAvatar(imageView, bitmap);
  }
};

protected static void loadAvatar(ImageView iv, Bitmap b) {
    iv.setImageBitmap(b);
}

そしてもちろん、disretrospect が上で述べたように、リサイクルされた convertViews に注意する必要があります。

LazyList の完全な例を作成し、ソースを投稿しました。 ListView での画像の遅延読み込みにも役立つ場合があります。

于 2010-06-02T14:14:31.897 に答える
1

Webから画像をダウンロード/キャッシュするためのこの素晴らしいライブラリがあります https://github.com/koush/UrlImageViewHelper

画像ビューと URL を入力するだけで完了です =)

于 2011-05-06T21:51:45.623 に答える