Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListView is very slow- android

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. :)

like image 484
aditmohan96 Avatar asked Jun 20 '15 10:06

aditmohan96


3 Answers

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

like image 87
Psypher Avatar answered Nov 04 '22 18:11

Psypher


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.

like image 3
aqel Avatar answered Nov 04 '22 19:11

aqel


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);
like image 2
Nicolas Avatar answered Nov 04 '22 19:11

Nicolas