Listview reloading already loaded images using Universal image loader
Asked Answered
P

2

6

In my Android project I am showing all images from web service(Url) to ListView for this purpose I have used Universal image loader. After loaded some images in List if I scrolled down then scrolled Up,The already loaded images are reloading again.

 DisplayImageOptions.Builder displayImageOptionsBuilder = new DisplayImageOptions
                    .Builder().cacheOnDisk(true).cacheInMemory(true).considerExifParams(true);


 ImageLoader.getInstance().displayImage(imageUri, imageView,
                  displayImageOptionsBuilder.build());

What I tried

ImageAware imageAware = new ImageViewAware(imageView, false);
            ImageLoader.getInstance().displayImage(imageUri, imageAware,displayImageOptionsBuilder.build());

Even used this code it wouldn't make any changes in ListView reloading

Edited

Adapter Class

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final String name = getItem(position);
        View view = convertView;    

        if (view == null) {
            view = createView();
            ViewHolder viewHolder = new ViewHolder();    
            viewHolder.image = (ImageView) view.findViewById(R.id.capsule_media_list_item_thumbnail_1);             
            view.setTag(viewHolder);    
        }

ImageHelper.initImage(viewHolder.image,
                imageUrl,
                R.drawable.vx_loading, loadingImageResource,displayOptionsCustomizer);

return view;
}

 private final DisplayOptionsCustomizer displayOptionsCustomizer = new DisplayOptionsCustomizer() {

        @Override
        public void customizeImageOptions(DisplayImageOptions.Builder displayImageOptionsBuilder) {
            displayImageOptionsBuilder.displayer(new RoundedBitmapDisplayer(ApplicationUtils
                    .dipToPixelsRounded(6, getContext()), 0));
        }
    };    

static class ViewHolder {
        public ImageView image;

    }

ImageHelper.java

public static void initImage(final ImageView imageView, final String imageUri,
                                 final int noImageResource, final int loadingImageResource,
                                 final DisplayOptionsCustomizer displayOptionsCustomizer) {
        if (StringUtils.isNotBlank(imageUri)) {             

            DisplayImageOptions.Builder displayImageOptionsBuilder = new DisplayImageOptions
                    .Builder().cacheOnDisk(true).cacheInMemory(true).considerExifParams(true);
            displayImageOptionsBuilder.showImageOnLoading(loadingImageResource)
                    .showImageOnFail(noImageResource);
            if (displayOptionsCustomizer != null) {
                displayOptionsCustomizer.customizeImageOptions(displayImageOptionsBuilder);
            }


           ImageLoader.getInstance().displayImage(imageUri, imageView,
                   displayImageOptionsBuilder.build());
        } else {
            if (noImageResource != 0) {
                imageView.setImageResource(noImageResource);
            } else {
                imageView.setVisibility(View.GONE);
            }
        }
    }

Edited Adapter class as per Dhir Pratap answer

public class ImagesListAdapter extends ArrayAdapter<String> {

private List imagesList = new ArrayList<String>();
private Context context;
ImageLoader imageLoader;
DisplayImageOptions options;

public ImagesListAdapter(Context context, List<String> imagesList) {
        super(context, -1,imagesList);
        this.imagesList = imagesList;
        this.context = context;
imageLoader = ImageLoader.getInstance();
 options = new DisplayImageOptions.Builder().cacheInMemory(true)
        .cacheOnDisk(true).resetViewBeforeLoading(true)
        .showImageForEmptyUri(fallbackImage)
        .showImageOnFail(fallbackImage)
        .showImageOnLoading(fallbackImage).build();

    }    

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final String name = getItem(position);
        View view = convertView;    
 ViewHolder viewHolder;

        if (view == null) {
            view = createView();
            viewHolder = new ViewHolder();    
            viewHolder.image = (ImageView) view.findViewById(R.id.capsule_media_list_item_thumbnail_1);             
            view.setTag(viewHolder);    
        }
else{

viewHolder =  (ViewHolder) view.getTag(viewHolder); 
}

/*ImageHelper.initImage(viewHolder.image,
                imageUrl,
             R.drawable.vx_loading, loadingImageResource,displayOptionsCustomizer);*/

imageLoader.displayImage(imageUrl,viewHolder.image,
           options);

return view;
}

/* private final DisplayOptionsCustomizer displayOptionsCustomizer = new DisplayOptionsCustomizer() {

        @Override
        public void customizeImageOptions(DisplayImageOptions.Builder displayImageOptionsBuilder) {
            displayImageOptionsBuilder.displayer(new RoundedBitmapDisplayer(ApplicationUtils
                    .dipToPixelsRounded(6, getContext()), 0));
        }
    };   */ 

static class ViewHolder {
        public ImageView image;

    }

}
Pamalapamela answered 22/1, 2015 at 9:56 Comment(4)
your question is unclear ... how did you use ImageLoader in getView of Adapter? How large are the images(it is important as image loaders can release cached bitmaps when memory is low - so it have to reaload it from disk cache or even from the internet(see next question))? Also does the server use e-tag(or other caching headers)?Shafer
@Shafer I have edited my question with Adapter class getView() method too.Pamalapamela
Image sizes are differ,every image has it own size.they are likely 14.1 kb,13.2 kb,27 kb,23.4 kb, 11 kb etc.Pamalapamela
by size i meant width and height as on disk size means nothing if you take Bitmap class into account ... still, most important is if caching is enabled on the serverShafer
S
12

There are few fixes you can do

  1. Your view holder is almost useless. You have to use it as follow

    ViewHolder viewHolder;
    if (view == null) {
        viewHolder = new ViewHolder();    
        viewHolder.image = (ImageView) view.findViewById(R.id.capsule_media_list_item_thumbnail_1);             
        view.setTag(viewHolder);    
    }else{
     viewHolder =  view.getTag(viewHolder); 
    }
    
  2. You should declare the ImageLoader and DisplayImageOptions instance only once. Probably in constructor.

    ImageLoader imageLoader = ImageLoader.getInstance();
    DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true)
            .cacheOnDisc(true).resetViewBeforeLoading(true)
            .showImageForEmptyUri(fallbackImage)
            .showImageOnFail(fallbackImage)
            .showImageOnLoading(fallbackImage).build();
    
  3. In the get view you simply load the image as follow

Edit: I had not used ImageAware. You have to use like this.

ImageAware imageAware = new ImageViewAware(viewHolder.image, false);
imageLoader.displayImage(imageUri, imageAware,options);

The answer here says that this indeed was an issue with the UIL which was fixed in version 1.9.

Edit 2: I followed the discussion on the issue at Github and found this answer which does manual checking on the image url. It suggests to do the following

//lets prevent "blinking" by "saving URL tag" hack

    if (viewHolder.image.getTag() == null ||
            !viewHolder.image.getTag().equals(imageUri)) {

        //we only load image if prev. URL and current URL do not match, or tag is null

        ImageAware imageAware = new ImageViewAware(viewHolder.image, false);
        imageLoader.displayImage(imageUri, imageAware,options);
        viewHolder.image.setTag(imageUri);
    }
Start answered 23/1, 2015 at 11:42 Comment(5)
Dhir Pratap,I have tried your code but still that issue happens. cacheOnDisc(true) method is deprecated so I tried with cacheOnDisk(true) tooPamalapamela
Can you update the question with the changes then I can look further.Start
I have tried your all edited answers but still the issue persist.Initially I used UIL library version 1.9.2 now I updated with 1.9.3 but still there is loading issuePamalapamela
I'm afraid I'm out of ideas. I downloaded the sample app for UIL and found this issue occurs in grid list but normal list was working fine. In sample code i saw options had another property set with .considerExifParams(true). Anyway until we get the correct answer I suggest try alternate libraries such as Picasso or Ion. I personally use Ion to load image and sending web request .Start
Working like a charm +1 :)Tineid
A
0

I have same problem. Putting ApplicationClass.java file in src folder and registering it to manifest file will solve your problem.

Here is both files:

ApplicationClass.java

package yourPackageName;

import android.app.Application;

import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;

public class ApplicationClass extends Application 
{
    @Override
    public void onCreate() {
        super.onCreate();

        // UNIVERSAL IMAGE LOADER SETUP
        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder().cacheOnDisc(true).cacheInMemory(true)
                .imageScaleType(ImageScaleType.EXACTLY).displayer(new FadeInBitmapDisplayer(300)).build();

        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
                .defaultDisplayImageOptions(defaultOptions).memoryCache(new WeakMemoryCache())
                .discCacheSize(100 * 1024 * 1024).build();

        ImageLoader.getInstance().init(config);
        // END - UNIVERSAL IMAGE LOADER SETUP
    }
}

Manifest file:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="yourPackageName">

    <!--Permissions -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
     android:name="com.webcluesinfotech.loadimagefromurlinlistview.ApplicationClass"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Hope this will help you.

Aeriform answered 11/12, 2015 at 12:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.