Android – loading images from SD Card in ListView

ListView is a very common widget in Android to show list. Now to show a list with images from web url can be done using several libraries like Fresco, Glide, Volley etc but loading images from SD Card or local storage is little tricky as it takes longer time to load and which results jerk in scroll of the listview. To solve this issue you need to load the images asynchronously within the listview adapter.

The above list is a sample contact list for illustration. Lets have a look into the code to implement lazy loading.

Step 1 – AsyncTask implementation

First of all you need an inner class extending AsyncTask to lazy load images within adapter class of the listview, here is the code for that –

private class LoadImageTask extends AsyncTask<Void, Bitmap, Void> {
        final String filePath;
        final ImageView ivProfile;

        LoadImageTask(String filePath, ImageView ivProfile) {
            this.filePath = filePath;
            this.ivProfile = ivProfile;
        }

        @Override
        protected Void doInBackground(Void... params) {
            final File photoPath = new File(filePath);
            if (photoPath.exists()) {
                Bitmap bitmap = BitmapUtility.decodeFile(photoPath);
                publishProgress(bitmap);
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Bitmap... values) {
            super.onProgressUpdate(values);
            Bitmap bitmap = values[0];
            if (bitmap != null) {
                ivProfile.setImageBitmap(bitmap);
            }
        }
    }

READ MORE – Styling custom views in Android

 

┬áStep 2 – AsyncTask reference

Once the inner class is added within the Adapter class you are all set to load the images from SD Card smoothly. You have to call the above inner class from the getView method of the adapter. Here is a sample of getView method after calling this inner class –

    @Nullable
    public View getView(final int position, @Nullable View convertView, ViewGroup viewGroup) {
        final Holder holder;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.contact_view, viewGroup, false);
            holder = new Holder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (Holder) convertView.getTag();
        }

        ContactDTO contact = getItem(position);
        if (contact != null) {
            if (contact.getPhoto() == null || contact.getPhoto().isEmpty()) {
                holder.photo.setImageResource(R.drawable.no_image);
            } else {
                new LoadImageTask(contact.getPhoto(), holder.photo).execute();
            }
            holder.name.setText(contact.getName().trim());
        }

        return convertView;
    }

Now loading images from SD Card in your listview is done without any jerk/lag which gives your user a great user experience.

 

I hope this will be useful for you, so do not forget to share this with your friends and colleagues.

Happy coding!!!

Leave a Reply

Your email address will not be published. Required fields are marked *