【问题标题】:Loading large Images into Listview将大图像加载到 Listview
【发布时间】:2015-02-13 22:22:34
【问题描述】:

所以我的 Listview 一直滞后,因为我在其中加载了太多图片。于是上网搜了一下,找到了两个特别的思路来解决这个问题:

  1. 使用 AsyncTask,如提到的 here
  2. 缩小图像,如提到的here

因此,由于我是使用 Android 开发的新手,所以我尝试了 AsyncTask 并失败了。我看到的示例主要是使用 URL 来下载图片,并且由于我使用的是 sqlite DB,所以我无法让这些示例为我工作。

所以这是我的尝试:

static class ViewHolder {
    TextView imageTextView;
    ImageView favImageView;
    int position;
}

//Constructor for List Items
private class favImagesListAdapter extends ArrayAdapter<FavImages>{
    private LayoutInflater mInflater = LayoutInflater.from(context);

    public favImagesListAdapter(){
        super (MainActivity.this, R.layout.listview_item, FavImages);
    }



    @Override
    public View getView (final int position, View convertView, ViewGroup parent){

        ViewHolder holder;

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.listview_item, parent, false);
            holder = new ViewHolder();
            holder.imageTextView = (TextView) convertView.findViewById(R.id.favName);
            holder.favImageView = (ImageView) convertView.findViewById(R.id.favImage);

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

        FavImages currentFav = FavImages.get(position);

        holder.imageTextView.setText(currentFav.getImageName());

        new AsyncTask<ViewHolder, Void, Bitmap>() {
            private ViewHolder v;


            @Override
            protected Bitmap doInBackground(ViewHolder... params) {
                v = params[0];
                return mFakeImageLoader.getImage();
            }

            @Override
            protected void onPostExecute(Bitmap result) {
                super.onPostExecute(result);
                if (v.position == position) {
                    // If this item hasn't been recycled already, hide the
                    // progress and set and show the image
                    //v.progress.setVisibility(View.GONE);
                    v.favImageView.setVisibility(View.VISIBLE);
                    v.favImageView.setImageBitmap(result);
                }
            }
        }.execute(holder);

        //old Version that causes lags
            ContentResolver cr = getContentResolver();
            try {
                holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav.getImagePath()));
            } catch (IOException e) {
                e.printStackTrace();
            }


        return convertView;
    }
}

由于我没有参考 FakeImageLoader 的作用,因此我尝试减小其中的图像大小,但没有奏效,因此我参考了我在 google 网站上找到的参考代码,如下所示:

public class FakeImageLoader {
private Bitmap mBmp;

public FakeImageLoader(Context cxt)
{
    mBmp= BitmapFactory.decodeResource(cxt.getResources(), R.drawable.ic_launcher);
}


public Bitmap getImage()
{
    try {
        Thread.sleep(new Random().nextInt(5000));
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return mBmp;
}
}

但是使用该类只会导致错误(因为用于完全不同的东西?)。

所以我在问,我需要 FakeImageLoader(可能不是一个好名字)来做什么,以最好地加载图像(猜测只需要缩小图像),主要是我该怎么做。

我也读过有关毕加索的文章,但我想保持应用程序小巧并通过做(或问)来学习。如果有更多代码有帮助,如果有要求,我会这样做。

编辑:

使用 FakeImageLoader 类不起作用(实际上很明显),所以我将整个 ListAdapter 与 Asynctask 更改为:

static class ViewHolder {
    TextView imageTextView;
    ImageView favImageView;
    int position;
}

//Constructor for List Items
private class favImagesListAdapter extends ArrayAdapter<FavImages>{
    private LayoutInflater mInflater = LayoutInflater.from(context);

    public favImagesListAdapter(){
        super (MainActivity.this, R.layout.listview_item, FavImages);
    }



    @Override
    public View getView (final int position, View convertView, ViewGroup parent){

        ViewHolder holder;

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.listview_item, parent, false);
            holder = new ViewHolder();
            holder.imageTextView = (TextView) convertView.findViewById(R.id.favName);
            holder.favImageView = (ImageView) convertView.findViewById(R.id.favImage);

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

        final FavImages currentFav = FavImages.get(position);

        holder.imageTextView.setText(currentFav.getImageName());

        class MyAsyncTask extends AsyncTask<ViewHolder, Void, Bitmap> {
            private ViewHolder v;

            @Override
            protected Bitmap doInBackground(ViewHolder... params) {
                v = params[0];
                return getImage();
            }

            private Bitmap getImage() {
                Bitmap mBmp;
                ContentResolver cr = getContentResolver();
                MainActivity.ViewHolder holder = null;
                com.adrianopaulus.favoriten.FavImages currentFav1 = FavImages.get(position);
                try {
                    mBmp = holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav1.getImagePath()));
                    return mBmp;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    return null;
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            //return mBmp;
            }

            @Override
            protected void onPostExecute(Bitmap result) {
                super.onPostExecute(result);
                if (v.position == position) {
                    // If this item hasn't been recycled already, hide the
                    // progress and set and show the image
                    //v.progress.setVisibility(View.GONE);
                    v.favImageView.setVisibility(View.VISIBLE);
                    v.favImageView.setImageBitmap(result);
                }
            }
        }MyAsyncTask.execute((Runnable) holder);

        return convertView;
    }
}

但它有些有以下行的问题:

mBmp = holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav1.getImagePath()));

我不知道自己做错了什么。

【问题讨论】:

    标签: android listview bitmap android-asynctask


    【解决方案1】:

    利用通用图像加载器库。这会异步加载图像,并且不会滞后于您的列表视图。

    https://github.com/nostra13/Android-Universal-Image-Loader

    里面有一个例子。

    享受:)

    【讨论】:

    • 正如我所说,我不想使用外部库。毫无疑问,通用图像加载器似乎很棒(非常感谢),但我宁愿拥有自己的代码。
    • 如果你不使用库,你还有很多工作要做 :-) 有一个教程 here,还有一个相关的 SO 问题 here
    【解决方案2】:

    //Aquery 的图像加载延迟加载。

    //尝试使用查询在列表视图中加载图像

    http://programmerguru.com/android-tutorial/introduction-to-aquery-android-query/

            AQuery aq = aq = new AQuery(convertView);
            // id means -> ImageView object or Imageview id
            // path means-> Url of Image.
            //Download a jar file, Copy and Past into a lib folder.
            aq.id(imgDisplay).image(path,true, true, 0,R.drawable.default_image, null,AQuery.CACHE_DEFAULT,0.0f).visible(); 
    

    【讨论】:

      猜你喜欢
      • 2017-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多