将大图像加载到列表视图中

Loading large Images into Listview

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

  1. 使用 AsyncTask,如前所述here
  2. 缩小图像,如前所述here

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

这是我的尝试:

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 的功能,我尝试减小其中图像的大小,但没有用,所以我使用了在 [=49 上找到的参考代码=] 像这样的网站:

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;
}
}

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

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

我也读过关于 Picasso 的文章,但我想保持 App 小巧,边做边学(或问)。如果更多代码有帮助,我会在询问时这样做。

编辑:

使用 FakeImageLoader class 不起作用(实际上很明显),所以我将整个 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()));

而且我不知道我做错了什么。

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

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

里面有例子。

尽情享受吧:)

//延迟加载用于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();