ListView is very slow- android
Asked Answered
M

3

8

I want to show images from the resource directory (all of them are saved in png format) in my ListView, but it is extremely laggy. I am a complete noob so I need help with the asynchronous tasks to remove lags.

List Adapter:

   public class MyListAdapter extends ArrayAdapter < SettingsItem > {

     Context context;
     List < SettingsItem > items;
     public MyListAdapter(Context context, int resource, List < SettingsItem > objects) {
       super(context, resource, objects);
       this.context = context;
       items = objects;
     }

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

       ViewHolder holder;
       if (itemView == null) {
         LayoutInflater inflater = ((Activity) context).getLayoutInflater();
         itemView = inflater.inflate(R.layout.settings_items, parent, false);

         holder = new ViewHolder();
         holder.imageView = (ImageView) itemView.findViewById(R.id.item_icon);
         holder.textView = (TextView) itemView.findViewById(R.id.item_text);

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

       SettingsItem settingsItem = items.get(position);

       if (settingsItem != null) {
         holder.textView.setText(settingsItem.getName());
         new ImageDownloaderTask(holder.imageView, getContext(), settingsItem.getIcon_id()).execute();
       }
       return itemView;
     }
     static class ViewHolder {
       ImageView imageView;
       TextView textView;
     }
   }

Row class:

public class SettingsItem{
    private String name;
    private int icon_id;
    public SettingsItem(String a, int b){

        super();
        name=a;
        icon_id=b;
    }

    public String getName() {
        return name;
    }

    public int getIcon_id() {
        return icon_id;
    }
}

AsyncTask:

class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    Context context;
    int id;
    public ImageDownloaderTask(ImageView imageView, Context context, int id) {
        imageViewReference = new WeakReference<ImageView>(imageView);
        this.context=context;
        this.id=id;
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        return BitmapFactory.decodeResource(context.getResources(),id );
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (isCancelled()) {
            bitmap = null;
        }

        if (imageViewReference != null) {
            ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                if (bitmap != null) {
                    imageView.setImageBitmap(bitmap);
                } else {
                    imageView.setImageResource(R.drawable.medical_bag);
                }
            }
        }
    }
}

I really need some help with this.
Thanks in advance. :)

Meaningful answered 20/6, 2015 at 10:53 Comment(3)
Your code doesn't look bad. What size/resolution are the images? On what device are you testing it?Pilloff
use Thread instead AsyncTaskVinegar
@Pilloff image sizes are 500x500.Testing on the oneplusMeaningful
C
4

I would recommend you to use the Glide library, this would bring get performance to image loading in your app and its pretty easy to use. It supports fetching, decoding, and displaying video stills, images, and animated GIFs too.

It makes scrolling any kind of a list of images as smooth and fast as possible, but Glide is also effective for almost any case where you need to fetch, resize, and display a remote image.

Glide is a fast and efficient open source media management and image loading framework for Android that wraps media decoding, memory and disk caching, and resource pooling into a simple and easy to use interface.

Adding Glide to your project:

dependencies {
    compile 'com.github.bumptech.glide:glide:3.6.0'
    compile 'com.android.support:support-v4:19.1.0'
}

For a listview usage from the official page is as below:

@Override
public View getView(int position, View recycled, ViewGroup container) {
    final ImageView myImageView;
    if (recycled == null) {
        myImageView = (ImageView) inflater.inflate(R.layout.my_image_view,
                container, false);
    } else {
        myImageView = (ImageView) recycled;
    }

    String url = myUrls.get(position);

    Glide.with(myFragment)
        .load(url)
        .centerCrop()
        .placeholder(R.drawable.loading_spinner)
        .crossFade()
        .into(myImageView);

    return myImageView;
}

For reference another project that uses this library for faster image loading and better scrolling: https://github.com/chrisbanes/cheesesquare

Cooke answered 20/6, 2015 at 11:8 Comment(0)
E
3

To create complex lists in your apps, you can use the RecyclerView. Read more about recycler view in https://developer.android.com/training/material/lists-cards.html.

For displaying images, use glide. https://github.com/bumptech/glide. It is an awesome library which does all the memory management for you. Loading bitmaps in imageview is slightly painful.

Enterovirus answered 20/6, 2015 at 11:8 Comment(0)
C
2

You can use the cache to have faster display. I am using picasso http://square.github.io/picasso it's really usefull to easily display pictures and handle the cache. Hope it helps.

Picasso.with(context).load("file:///android_asset/DvpvklR.png").into(imageView2);
Contexture answered 20/6, 2015 at 11:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.