Android で ListView に非同期で取ってきた画像を表示

1にしか画像ファイルはないんだけど・・・・

device1

 

 

 

 

 

 

 

 

 

 

下にスクロールすると6にも7にも・・・

device2

 

 

原因は、 ListView 内で contentview を使いまわしてるから、
非同期で取ってくると参照がずれる。

 

Adapter.getView()

 

  1. @Override
  2. public View getView(int position, View convertView, ViewGroup parent) {
  3. final ListItem listItem = (ListItem) getItem(position);
  4. ViewHolder holder;
  5. if (convertView == null) {
  6. convertView = layoutInflater.inflate(resourceId, null);
  7. holder = new ViewHolder();
  8. holder.thumbnail = (ImageView) convertView.findViewById(R.id.thumbnail);
  9. holder.title = (TextView) convertView.findViewById(R.id.title);
  10. holder.explain = (TextView) convertView.findViewById(R.id.explain);
  11. holder.nextButton = (ImageView) convertView.findViewById(R.id.nextButton);
  12. convertView.setTag(holder);
  13. } else {
  14. holder = (ViewHolder) convertView.getTag();
  15. }
  16. // 画像を非表示
  17. holder.thumbnail.setVisibility(View.GONE);
  18. // ImageView にタグを設定
  19. // このタグを AsyncTask で使います。
  20. holder.thumbnail.setTag(listItem.thumbnailUrl);
  21. // 非同期通信開始
  22. DownloadTask task = new DownloadTask(holder.thumbnail);
  23. task.execute(listItem.thumbnailUrl);
  24. // テキストは普通にセットする
  25. holder.title.setText(listItem.title);
  26. holder.explain.setText(listItem.explain);
  27. return convertView;
  28. }

 

DownloadTask

 

  1. class DownloadTask extends AsyncTask<String, Drawable, Void> {
  2. private ImageView imageView;
  3. private String tag;
  4. public DownloadTask(ImageView imageView) {
  5. this.imageView = imageView;
  6. // ImageView に設定したタグをメンバへ
  7. this.tag = imageView.getTag().toString();
  8. }
  9. @Override
  10. protected Drawable doInBackground(String… urls) {
  11. synchronized (context) {
  12. try {
  13. Drawable image = ImageCache.get(urls[0]);
  14. if (image == null) {
  15. URL url = new URL(urls[0]);
  16. image = Drawable.createFromStream((InputStream) url.getContent(), “”);
  17. ImageCache.set(urls[0], image);
  18. }
  19. return image;
  20. } catch (MalformedURLException e) {
  21. // TODO Auto-generated catch block
  22. e.printStackTrace();
  23. } catch (IOException e) {
  24. // TODO Auto-generated catch block
  25. e.printStackTrace();
  26. }
  27. return null;
  28. }
  29. }
  30. @Override
  31. protected void onPostExecute(Drawable result) {
  32. // メンバのタグと imageView にセットしたタグが一致すれば
  33. // 画像をセットする
  34. if (this.tag.equals(this.imageView.getTag())) {
  35. if (result != null) {
  36. this.imageView.setImageDrawable(result);
  37. this.imageView.setVisibility(View.VISIBLE);
  38. }
  39. }
  40. }
  41. }