加载图片自定义列表视图 - 如何逐步加载? [英] Loading images to custom listview - how to gradually load?

查看:169
本文介绍了加载图片自定义列表视图 - 如何逐步加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义的列表视图 - 其中包含一个ImageView的,文本和一个复选框

我从Dropbox的是加载图像(取thumnails否则获取共享URL的图像)和我使用它们载入自定义列表视图的 ImageAdapter

这是加载图像在一个特定的文件夹非常缓慢。它需要几秒钟,如果有几十只加载一些图片,长达一分钟,我与我的应用程序崩溃承担内存异常,如果有大量的图片。

这似乎是服用约2秒,得到的Dropbox的URL(或获取位图,如果你去code中的流)。因此,它正在采取60秒中检索30个图像的URL。 (它为什么这么长时间不知道?)这是很过分的。

我希望我能提高我的code是快了很多。我想逐步加载图像,即保持UI响应并加载图像批次。

我已经在使用一个异步任务,所以希望有人能提供意见。

请注意,我已经使用通用图像装载机尝试,它仍然需要很长的时间来加载图像。

我要指出,我认为这个问题是从下拉框检索图像数据。低于code检索缩略图文件,并且是很慢的。我曾试图改变code,而不是获取URL链接的图像,但是这又是非常缓慢的执行和循环。

那么,有河套内的任何方式来获得的图像 开始显示在ListView中的数据,在循环完成之前这是 - ?唐T等到 OnTaskCompleted - 而是开始显示内的图像 doInBackground

下面是 doInBackground 的异步任务:

  @覆盖
    保护布尔doInBackground(DbxFileSystem ... PARAMS){
        //打开缩略图中包含的收存箱文件夹的每个图像
        尝试{
            DbxFileSystem文件系统=参数[0];
            为(DbxFileInfo的fileInfo:fileSystem.listFolder(currentPath)){
                DbxFile文件;//这个code以下是执行速度很慢
                尝试{
                    如果(fileInfo.thumbExists)//如果它有一个缩略图,然后检索
                    {
                        文件= fileSystem.openThumbnail(fileInfo.path,ThumbSize.XS,ThumbFormat.PNG);
                        位图图像= BitmapFactory.de codeStream(file.getReadStream());
                        pix.add(图片); //形象自定义列表视图显示
                        paths.add(fileInfo.path); //路径在自定义列表视图显示                        file.close();
                    }
                    其他
                    {
                        //必须是一个文件夹,如果它没有经验,所以添加本地绘制文件夹图标
                        位图图像= BitmapFactory.de codeResource(getResources(),R.drawable.dbfolder);
                        pix.add(图片);
                        paths.add(fileInfo.path);                    }
                }赶上(DbxException E1){
                    e1.printStackTrace();
                }赶上(IOException异常五){
                    e.printStackTrace();
                }
                System.gc()的;
            }
        }
        赶上(例外五){
            e.printStackTrace();            返回false;
        } {最后
            loadingDialog.dismiss();
        }
        返回true;
    }

然后在onTaskCompleted是我们设定的图像适配器:

 公共无效onTaskCompleted(INT的requestId,ArrayList的<&位图GT;的URL,ArrayList的< D​​bxPath>路径){            lstView =(ListView控件)findViewById(R.id.lstView);
            this.paths =路径;            ImageAdapter适配器=新ImageAdapter(这一点,网址,路径);
            lstView.setAdapter(适配器);
}

这是的getView的 ImageAdapter.java

 公共查看getView(INT位置,查看ARG1,ARG2的ViewGroup){
        LayoutInflater吹气=(LayoutInflater)上下文
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);        查看GridView控件;
        GridView控件=新景(背景);        //膨胀image_helper布局
        GridView控件= inflater.inflate(R.layout.list_row,NULL);        //组图像
        ImageView的ImageView的=(ImageView的)GridView控件
                .findViewById(R.id.list_image);        imageView.setImageBitmap(images.get(位置));        TextView中的TextView =(TextView的)GridView控件
                .findViewById(R.id.filename);           textView.setText(folderName.get(位置)的ToString());        返回GridView控件;
    }


解决方案

有关这个你可以使用通用的图像加载的jar 通用图像装载-1.9.2-快照与-sources.jar

然后适配器是这样的。

 公共类LinkAdapter扩展ArrayAdapter< MediaModel> {    ArrayList的< MediaModel>媒体;
    活动背景;
    ImageLoader的ImageLoader的;
    DisplayImageOptions选择;    公共LinkAdapter(活动的背景下,INT textViewResourceId,
            ArrayList的< MediaModel>对象){
        超(背景下,textViewResourceId,对象);
        this.medias =物体;
        this.context =背景;
        ImageLoader的= ImageLoader.getInstance();
        imageLoader.init(ImageLoaderConfiguration.createDefault(上下文));
        选项​​=新DisplayImageOptions.Builder()
        .showImageOnLoading(R.drawable.ic_launcher)
        .showImageForEmptyUri(R.drawable.ic_launcher)
        .showImageOnFail(R.drawable.ic_launcher).cacheInMemory(真)
        .cacheOnDisc(真).considerExifParams(真)
        .bitmapConfig(Bitmap.Config.RGB_565).build();
    }    静态类ViewHolder {
        TextView的称号;
        TextView的描述;
        ImageView的iconImage;
    }    @覆盖
    公共查看getView(INT位置,查看convertView,父母的ViewGroup){
        视图V = convertView;
        ViewHolder持有人;        如果(convertView == NULL){
            LayoutInflater VI =(LayoutInflater)的getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            V = vi.inflate(R.layout.link_row,NULL);            持有人=新ViewHolder();
            holder.title =(TextView中)v.findViewById(R.id.txt_row_title);
            holder.description =(TextView中)v.findViewById(R.id.txt_row_description);
            holder.iconImage =(ImageView的)v.findViewById(R.id.img_row_icon);
            v.setTag(保持器);
        }其他{
            支架=(ViewHolder)v.getTag();
        }        holder.title.setText(medias.get(位置).mediaTitle);
        holder.description.setText(medias.get(位置).mediaInfo);
        imageLoader.displayImage(medias.get(位置).mediaThumbImgUrl,holder.iconImage,期权);        返回伏;
    }}

I have a custom Listview - which contains an imageView, text and a checkbox.

I am loading images from dropbox (taking the thumnails or else getting the shared URL to the image) and I am loading them into the custom Listview using an ImageAdapter.

It is very slow to load the images in a given folder. It takes several seconds just to load a few images, up to a minute if there are dozens, and my app crashes with I assume an Out of Memory exception if there are lots of images.

It seems to be taking about 2 seconds to get the URL from dropbox (or get the Bitmap if you decode the stream). So it is taking 60 seconds to retreive 30 image URLs. This is very excessive (not sure why it is taking so long?)

I am hoping I can improve my code to be a lot faster. I would like to load the images incrementally, i.e. keep the UI responsive and load the images in batches.

I am already using an Async task, so hopefully someone can advise.

Note that I have tried using Universal Image Loader and it still takes a long time to load the images.

I should note that I think the problem is in retrieving the image data from dropbox. The code below retrieves the thumbnail file, and is very slow. I have tried changing the code to instead retrieve the URL link to the image, but again it is very slow to execute and loop.

So is there any way inside of the Loop to get the images, to start displaying the data in the ListView, before the loop has completed? That is - don't wait until the OnTaskCompleted - but rather start displaying the images inside of the doInBackground?

Here is the doInBackground of the Async Task:

 @Override
    protected Boolean doInBackground(DbxFileSystem... params) {
        //Opens thumbnails for each image contained in the dropbox folder
        try {
            DbxFileSystem fileSystem = params[0];


            for (DbxFileInfo fileInfo: fileSystem.listFolder(currentPath)) {
                DbxFile file;

//this code below is very slow to execute
                try{
                    if(fileInfo.thumbExists) // if it has a thumbnail then retrieve it
                    {
                        file = fileSystem.openThumbnail(fileInfo.path, ThumbSize.XS, ThumbFormat.PNG);
                        Bitmap image = BitmapFactory.decodeStream(file.getReadStream());
                        pix.add(image);  // image to display in the custom listview
                        paths.add(fileInfo.path); // path to display in the custom listview

                        file.close();                     
                    }
                    else
                    {
                        //must be a folder if it has no thumb, so add local drawable folder icon
                        Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.dbfolder);
                        pix.add(image);
                        paths.add(fileInfo.path);                   

                    }
                }catch (DbxException e1) {
                    e1.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.gc();
            }
        }
        catch (Exception e) {
            e.printStackTrace();

            return false;
        } finally {
            loadingDialog.dismiss();
        }
        return true;
    }

Then in the onTaskCompleted is where we set the Image Adapter:

       public void onTaskCompleted(int requestID, ArrayList<Bitmap> urls, ArrayList<DbxPath> path) {

            lstView = (ListView) findViewById(R.id.lstView);
            this.paths = path;

            ImageAdapter adapter = new ImageAdapter(this, urls, paths);
            lstView.setAdapter(adapter);
}

This is the getView of the ImageAdapter.java:

    public View getView(int position, View arg1, ViewGroup arg2) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View gridView;


        gridView = new View(context);

        // inflate image_helper layout
        gridView = inflater.inflate(R.layout.list_row, null);

        // set images
        ImageView imageView = (ImageView) gridView
                .findViewById(R.id.list_image);

        imageView.setImageBitmap(images.get(position));

        TextView textView = (TextView) gridView
                .findViewById(R.id.filename);

           textView.setText(folderName.get(position).toString());

        return gridView;
    }

解决方案

For this you can use Universal Image loader jar universal-image-loader-1.9.2-SNAPSHOT-with-sources.jar

Then adapter is like this

public class LinkAdapter extends ArrayAdapter<MediaModel>{

    ArrayList<MediaModel> medias;
    Activity context;
    ImageLoader imageLoader;
    DisplayImageOptions options;

    public LinkAdapter(Activity context, int textViewResourceId,
            ArrayList<MediaModel> objects) {
        super(context, textViewResourceId, objects);
        this.medias = objects;
        this.context = context;
        imageLoader = ImageLoader.getInstance();
        imageLoader.init(ImageLoaderConfiguration.createDefault(context));
        options = new DisplayImageOptions.Builder()
        .showImageOnLoading(R.drawable.ic_launcher)
        .showImageForEmptyUri(R.drawable.ic_launcher)
        .showImageOnFail(R.drawable.ic_launcher).cacheInMemory(true)
        .cacheOnDisc(true).considerExifParams(true)
        .bitmapConfig(Bitmap.Config.RGB_565).build();
    }

    static class ViewHolder {
        TextView title;
        TextView description;
        ImageView iconImage;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        ViewHolder holder;

        if (convertView == null) {
            LayoutInflater vi = (LayoutInflater) getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.link_row, null);

            holder = new ViewHolder();
            holder.title = (TextView) v.findViewById(R.id.txt_row_title);
            holder.description = (TextView) v.findViewById(R.id.txt_row_description);
            holder.iconImage = (ImageView) v.findViewById(R.id.img_row_icon);
            v.setTag(holder);
        } else {
            holder = (ViewHolder) v.getTag();
        }

        holder.title.setText(medias.get(position).mediaTitle);
        holder.description.setText(medias.get(position).mediaInfo);
        imageLoader.displayImage(medias.get(position).mediaThumbImgUrl, holder.iconImage,options);

        return v;
    }

}

这篇关于加载图片自定义列表视图 - 如何逐步加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆