使用Image在ListView中进行延迟加载。 (光标适配器)

时间:2015-07-22 09:17:08

标签: android

我有一个列表视图,显示带有缩略图的视频,我正在使用游标适配器(使用ContentProvider获取)。问题是列表项的数量增加列表视图性能变得非常差。请让我知道延迟加载的最佳方法。

新: 最终我得到了一些解决方案。它对我来说很好。如果您有任何建议,请告诉我。 我的新代码就在这里。 (它使用堆栈与Producer Consumer patern和bacground线程进行处理)

@覆盖     public void bindView(View视图,Context context,Cursor cursor){

    ViewHolder holder = (ViewHolder) view.getTag();
    String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE));
    int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID));
    holder.getIdView().setText(name);
    holder.getThumbView().setTag((Integer)id);
    if(LazyLoader.getInstance().containsKey(id)) {
        Object bitmap = LazyLoader.getInstance().getBitMap(id);
        if(null != bitmap && (bitmap instanceof  Bitmap)) {
            holder.getThumbView().setImageBitmap((Bitmap)bitmap);
        } else {
            holder.getThumbView().setImageDrawable(null);
        }
    } else {
        holder.getThumbView().setImageDrawable(null);
        LazyItem lazyItem = new LazyItem();
        lazyItem.setId(id);
        lazyItem.setThumbNail(holder.getThumbView());
        LazyLoader.getInstance().putItem(lazyItem);
    }
}




public class LazyLoaderHelper extends Thread {

    private ContentResolver resolver = null;
    private Activity activity;
    private boolean isActive = true;
    ExecutorService executor;


    public LazyLoaderHelper(Activity _activity , ContentResolver _resolver) {
        resolver = _resolver;
        activity = _activity;
        isActive = true;
        executor = Executors.newFixedThreadPool(10);
    }

    public void stopThread() {
        isActive = false;
        executor.shutdown();
    }

    @Override
    public void run() {
        while (isActive) {
            if(LazyLoader.getInstance().getSize() > 0) {
                final  LazyItem lazyItem = LazyLoader.getInstance().getItem();
                if(null != lazyItem) {

                    executor.execute(new Runnable() {
                        @Override
                        public void run() {

                            BitmapFactory.Options options = new BitmapFactory.Options();
                            options.inSampleSize = 1;

                            if ((null != resolver) && (null != activity)) {
                                final Bitmap thumb = MediaStore.Video.Thumbnails.getThumbnail(resolver, lazyItem.getId(), MediaStore.Video.Thumbnails.MICRO_KIND, options);
                                if (null != thumb) {
                                    LazyLoader.getInstance().putBitMap(lazyItem.getId(), thumb);
                                } else {
                                    LazyLoader.getInstance().putBitMap(lazyItem.getId(), new Object());
                                }

                                if ((Integer) lazyItem.getThumbNail().getTag() == lazyItem.getId()) {
                                    activity.runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            if (null != thumb) {
                                                lazyItem.getThumbNail().setImageBitmap(thumb);
                                            } else {
                                                lazyItem.getThumbNail().setImageDrawable(null);
                                            }
                                        }
                                    });
                                }
                            }
                        }
                    });
                }
            }

        }
    }
}

6 个答案:

答案 0 :(得分:12)

你可以使用picaso库为android它是开源的,可以很容易地在你的应用程序中集成,你可以从下面链接从github下载库

http://square.github.io/picasso/

并且可以通过在列表视图适配器中使用以下方法轻松实现延迟加载

Picasso支持下载和错误占位符作为可选功能。

<强> Picasso.with(上下文)     .load(URL)     .placeholder(R.drawable.user_placeholder)     .error(R.drawable.user_placeholder_error)     .into(ImageView的);

资源,资产,文件,内容提供商都支持作为图像源。

<强> Picasso.with(上下文).load(R.drawable.landing_screen).into(imageView1); Picasso.with(上下文).load( “文件:///android_asset/DvpvklR.png”).into(imageView2); Picasso.with(context).load(new File(...))。into(imageView3);

答案 1 :(得分:4)

各种库可用于延迟加载图像。 毕加索&amp;滑翔非常好。整合也很容易。 如果图像质量最重要,您可以使用毕加索。 使用滑动可以加快装载速度。 虽然你可以选择任何人,但我建议使用Glide。

对于交换图像,图像的异步加载可能存在问题。 你怎么知道线程完成。任何线程都可以随时加载图像。

由于

答案 2 :(得分:2)

在我看来,你应该试试UIL (Universal Image Loader) 该lib可以显示视频缩略图以及图像缩略图。

编辑: 将imageLoader.displayImage(String uri, ImageView imgView, DisplayImageOptions options);添加到getView

custom adapter

字符串uri可以是file:///mnt/sdcard/video.mp4 //来自SD卡(视频缩略图)

希望这有帮助!如果您有任何问题,请在下面发表评论

答案 3 :(得分:2)

  • 我正在使用aQuery库来延迟加载位图(它也支持http)。它非常简单,易于与现有代码集成,无需进行大量更改。
  • 保持项目的布局尽可能简单。
  • 确保正确实施回收和查看持有人模式。

有关平滑列表滚动的更多信息是here

答案 4 :(得分:2)

我建议您将ViewHolder模式与名为Picasso的库结合使用。

加载图片时,毕加索看起来像是:

java.util.Date

希望它有所帮助。

答案 5 :(得分:2)

使用延迟加载是好的,但我仍然更喜欢Picasso安卓库,它会自动设置缓存需求,也会花费更少的时间来加载图像。我使用寻呼机适配器查看寻呼机动画,这里我要求的数量用于不同页面的图像。这是一个例子。

 public Object instantiateItem(ViewGroup container, int position) {
         final ViewGroup cnt=container;


             final int val=position;


             View itemView = mLayoutInflater.inflate(R.layout.smallnewsview, container, false);

            try
            {

             ImageView img=(ImageView)itemView.findViewById(R.id.imageView1);

             Picasso.with(context)
               .load("just image url....")
               .into(img, new Callback() {

          @Override
          public void onSuccess() {
            pbh.setVisibility(View.GONE);
          }

          @Override
          public void onError() {
              pbh.setVisibility(View.VISIBLE);
          }
        });

现在下次它每次都会自动调用缓存而不是服务器。我真的很喜欢这个图书馆。

在这里你也可以获得图书馆。

http://square.github.io/picasso/

我希望这对您的支持非常有帮助。