将大图像加载到Listview中

时间:2015-02-13 22:22:34

标签: android listview bitmap android-asynctask

所以我的Listview一直滞后,因为我加载了太多图片。所以我在网上搜索并发现了两个解决问题的特殊想法:

  1. 使用AsyncTask,如上所述here
  2. 缩小图片,如上所述here
  3. 因为我刚开始使用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的功能,我试图减少那里的图像大小,但它没有工作,所以我采用了我在谷歌上找到的参考代码网站如此:

    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(可能不是那么好的名字),最好加载图像(猜测只需要缩小图像),大部分我该怎么做。< / p>

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

    编辑:

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

    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()));
    

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

2 个答案:

答案 0 :(得分:1)

利用通用图像加载程序库。这会异步加载图像,并且它不会滞后于列表视图。

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

它有一个例子。

享受:)

答案 1 :(得分:0)

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

//尝试使用查询在listview中加载图片

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();