【问题标题】:Custom Listview shows nothing with AsyncTask自定义列表视图在 AsyncTask 中不显示任何内容
【发布时间】:2014-02-28 09:22:15
【问题描述】:

我正在使用代码将照片列表从图库加载到自定义水平列表视图中。 Listview 滚动不顺畅。我决定将加载照片放到背景中。但现在 listview 什么也没显示。你能给我任何帮助吗?经过一番讨论,我做了一些更正。但结果显示空列表视图。

Main.java

    public class Main extends Activity {
private HorizontalImageAdapter horizontalimageAdapter;
 private HorizontalListView listview;
 private Utilf utils;
 private ArrayList<String> imagePaths = new ArrayList<String>();

     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_horizontal_list_view);

         utils = new Utilf(this);
         imagePaths = utils.getFilePaths();
         listview = (HorizontalListView) findViewById(R.id.gallery);
         horizontalimageAdapter = new HorizontalImageAdapter(this, imagePaths);
         listview.setAdapter(horizontalimageAdapter);
     }
    }

Horizo​​ntalImageAdapter.java

public class HorizontalImageAdapter extends BaseAdapter {

 private Activity context;
 private static ImageView imageView;
 private ArrayList<String> plotsImages;
 private LayoutInflater l_Inflater;

 public HorizontalImageAdapter(Activity context, ArrayList<String> plotsImages) {
  this.context = context;
  this.plotsImages = plotsImages;
  l_Inflater = LayoutInflater.from(context);
 }

 @Override
 public int getCount() {
     return plotsImages.size();
 }

 @Override
 public Object getItem(int position) {
  return null;
 }

 @Override
 public long getItemId(int position) {
  return 0;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
     ViewHolder holder;
  if (convertView == null) {
   convertView = l_Inflater.inflate(R.layout.listview_item, null);
   holder = new ViewHolder();
   holder.imageView = (ImageView) convertView.findViewById(R.id.icon);

   convertView.setTag(holder);
  } else {
   holder = (ViewHolder) convertView.getTag();
  }

  if (holder.imageView != null) {
      new ImageDownloaderTask(holder.imageView).execute(plotsImages.get(position));
  }

  return convertView;

 }

 private static class ViewHolder {
  ImageView imageView;
 }
}

ImageDownloader.java

 class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
            private final WeakReference<ImageView> imageViewReference;
            private int imageWidth = 96;

            public ImageDownloaderTask(ImageView imageView) {
                imageViewReference = new WeakReference<ImageView>(imageView);
            }

        @Override
        protected Bitmap doInBackground(String... params) {
            Bitmap bitmap = loadBitmap(params[0]);
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (isCancelled()) {
                bitmap = null;
            }

            if (imageViewReference != null) {
                ImageView imageView = imageViewReference.get();
                if (imageView != null) {

                    if (bitmap != null) {
                        imageView.setImageBitmap(bitmap);
                    } else {
//                      imageView.setImageDrawable(imageView.getContext().getResources().getDrawable(R.drawable.list_placeholder));
                    }
                }

            }
        }

【问题讨论】:

  • 发布您的loadBitmap(....) 方法
  • onPostExecute中设置适配器
  • 这一行listview.setAdapter(mAdapter);必须在onPostExecute
  • 无意冒犯,但你为什么要重新发明轮子?创建 UIL (github.com/nostra13/Android-Universal-Image-Loader) 和 Picasso (github.com/square/picasso) 等库是为了帮助您准确地完成您的工作。
  • @SweetWisherツ,我认为他已经将适配器设置为列表视图。异步用于将图像加载到适配器内部的视图中。在我看来就是这样。

标签: android listview android-asynctask


【解决方案1】:

你不能这样做,因为你的 imageview 会被重复使用多次。 您需要一种方法来检查,一旦异步任务完成加载位图,您仍然在列表视图的完全相同的行上,否则您将在滚动列表视图时在随机位置显示图像。为此,您可以将位图 url 作为标签存储在 imageview 上,并在调用 setImageBitmap() 之前检查该标签。如果匹配,您可以显示位图,否则什么也不做。

但就像@HERO 所说,为什么不使用 Picasso 库,它会以更好的方式做到这一点;)

【讨论】:

  • 我需要水平列表视图。
  • 那么你需要使用 ViewPager 而不是 listview。但是,如果您显示到正确的图像视图中,您从异步任务加载图像的代码只会随机工作(参见我的答案)
  • ViewPager 不适用于我,因为我需要像画廊这样的小部件。 Imageview 不为空,所以它调用异步加载。
  • 我需要重新加载适配器吗?但是怎么做呢?
  • 是的,但是如果用户正在滚动,很可能图像视图已被回收,您将不会在您想要的位置显示图像。如果您想实现图库,ViewPager 就是您所需要的。我不明白你关于重新加载适配器的问题。请阅读我的回答,它解释了您的代码将面临的问题
【解决方案2】:
  • 列表项

    请检查您的getItem(int position) 方法。它返回空值。相反,您必须从列表中返回该位置本身的对象

  • getView() 方法

您直接返回 convertView。而是将其放入一个单独的变量中,如这段代码

 public View getView(int position, View convertView, ViewGroup parent) {
    View rowView = convertView;
    // reuse views
    if (rowView == null) {
      LayoutInflater inflater = context.getLayoutInflater();
      rowView = inflater.inflate(R.layout.rowlayout, null);
      // configure view holder
      ViewHolder viewHolder = new ViewHolder();
      viewHolder.text = (TextView) rowView.findViewById(R.id.TextView01);
      viewHolder.image = (ImageView) rowView
          .findViewById(R.id.ImageView01);
      rowView.setTag(viewHolder);
    }

    // fill data
    ViewHolder holder = (ViewHolder) rowView.getTag();
    String s = names[position];
    holder.text.setText(s);
    if (s.startsWith("Windows7") || s.startsWith("iPhone")
        || s.startsWith("Solaris")) {
      holder.image.setImageResource(R.drawable.no);
    } else {
      holder.image.setImageResource(R.drawable.ok);
    }

    return rowView;
  }

代码取自 this 链接

【讨论】:

  • 这没有帮助。我的代码运行良好,无需异步加载 exepting 平滑滚动。
猜你喜欢
  • 1970-01-01
  • 2021-05-01
  • 1970-01-01
  • 2014-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多