ListView scrolling using UniversalImageDownloader is not smooth

I am using a ListView containing images. These images are downloaded from the Internet inside the adapter. Therefore, I use UniversalImageDownloader .

Unfortunately, scrolling through the ListView is β€œlagging” for a short time, as soon as I scroll down to where to download new content.

I confidently expected that behavior like ListView scrolls perfectly smoothly, but loading an image can, of course, take longer - which should not affect the smoothness of scrolling.

In addition, when I scroll through the backup, lag also occurs. It seems that the images are not cached properly.

Perhaps my ImageLoader settings are not configured correctly?

Am I doing something wrong in my adapter?

ListView contains about 20-30 images with dimensions of 640x320 (about 150kb)

Below you can see my adapter, as well as ImageLoader. (The Downloader class is just a wrapper class for UniversalImageDownloader)

public class Downloader { /** * initializes the imagedownloader with a specific configuration * I CALL THIS METHOD RIGHT AFTER APP STARTUP * @param c */ public static void initialize(Context c) { // Create global configuration and initialize ImageLoader with this configuration ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(c) .threadPoolSize(20) .threadPriority(Thread.NORM_PRIORITY) // default .tasksProcessingOrder(QueueProcessingType.FIFO) // default .memoryCacheSize(20 * 1024 * 1024) .memoryCacheSizePercentage(15) // default .discCacheSize(20 * 1024 * 1024) .discCacheFileCount(100) .discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default .imageDecoder(new BaseImageDecoder()) // default .build(); ImageLoader.getInstance().init(config); } /** * gets the display options that are needed when displaying an image * @return */ public static DisplayImageOptions getDisplayOptions() { DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageForEmptyUri(R.drawable.error) .showImageOnFail(R.drawable.error) .resetViewBeforeLoading(false) // default .cacheInMemory(true) // default .cacheOnDisc(true) // default .build(); return options; } public static ImageLoader getInstance() { return ImageLoader.getInstance(); } } 

And adapter:

 public class EventListAdapter extends ArrayAdapter<Event> { private List<Event> mList; private DisplayImageOptions options; public EventListAdapter(Context context, int list_item_resource, List<Event> objects) { super(context, list_item_resource, objects); mList = objects; options = Downloader.getDisplayOptions(); } @Override public View getView(int position, View convertView, ViewGroup parent) { Event event = mList.get(position); // A ViewHolder keeps references to children views to avoid unneccessary calls to findViewById() on each row. ViewHolder holder = null; if (convertView == null) { LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.normalevent_list_item, parent, false); holder = new ViewHolder();; holder.eventimage = (ImageView) convertView.findViewById(R.id.ivEventImage); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } if (event != null) { holder.eventimage.setImageResource(R.drawable.loading); // Load image, decode it to Bitmap and display Bitmap in ImageView Downloader.getInstance().displayImage(event.getImageOneURL(), holder.eventimage, options); } return convertView; } private static class ViewHolder { ImageView eventimage; } } 
+4
source share
2 answers

I had the same problem downloading images. I solved this by setting delayBeforeLoading (1000) in my DisplayImageOptions. You must start the download when the user stops quitting.

try replacing the getDisplayOptions method with

  public static DisplayImageOptions getDisplayOptions() { DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageForEmptyUri(R.drawable.error) .showImageOnFail(R.drawable.error) .delayBeforeLoading(1000) .resetViewBeforeLoading(false) // default .cacheInMemory(true) // default .cacheOnDisc(true) // default .build(); return options; } 

The documentation also recommends using this code to avoid grid / list scrolling delays.

 boolean pauseOnScroll = false; // or true boolean pauseOnFling = true; // or false PauseOnScrollListener listener = new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling); listView.setOnScrollListener(listener); 

You can read it here (the last item in the "Useful Information" list)

So you can use one of these methods

+8
source

@Sergey Pekar: You saved my life! :) I always used UIL for ListView for a small number of images, but then, when the number increased, I always experienced a lag when I first loaded (while scrolling) the images. So I also tried the delay, and that helped a bit with other UIL settings and settings, but I was not happy. Then I tried different image loading libraries (Picasso, AQuery, Volley, UrlImageViewHelper, custom code). They all worked faster (on first boot) than UIL, but they did not have enough options for me. So, I was looking for the last 2 days to solve this problem with lag and bot, I finally found your message here! The solution was PauseOnScrollListener!

Which also (adding to PauseOnScrollListener) improves scroll smoothness a bit by extending ImageView to stop requestLayout as follows:

 public class CustomImageView extends ImageView { public CustomImageView (Context context, AttributeSet attributeset, int int_style) { super(context, attributeset, int_style); } public CustomImageView (Context context, AttributeSet attributeset) { super(context, attributeset); } public CustomImageView (Context context) { super(context); } @Override public void requestLayout() { // Do nothing here } } 

See this post for more details:
ListView is very slow when scrolling (using ViewHolder / recycling)

+1
source

Source: https://habr.com/ru/post/1496583/


All Articles