简体   繁体   中英

Images not loaded into ListView when scrolling fast

I have a long ListView in which there is an ImageView for each row. It displays the correct bitmaps if I slowly scroll the list (each row has different icon to show).

The problem comes up when I scroll the ListView fastly. It happens that many images are not loaded into their ImageView , leaving it transparent. Even the ones that were previously shown scrolling the list slowly.

Here is the code inside the getView() method that should display the icons:

      BitmapFactory.Options options = new BitmapFactory.Options();
      options.inPreferredConfig = Bitmap.Config.ARGB_8888;
      String name = ... //custom code to get the icon name to show
      Bitmap bitmap = BitmapFactory.decodeFile(getIconsDir() + name + getIconsExt(), options);
      holder.imgIcon.setImageBitmap(bitmap);

I'm recycling the convertView in the getView() method of the adapter.

I know for sure that the bitmap exists in that location. imgIcon is the ImageView referenced by the ViewHolder of the row.

I've also tried to use image loaders (like Picasso) but I got the same result.

Does anyone have experienced this before?

Do not do bitmap decoding in adapter's getView() . It will Cause ListView to lag and also fill up RAM very fast.

You should:

  1. Use a size limited, in-memory cache to hold onto bitmaps.
  2. Decode and Load images in Views asynchronously.

ListView re-cycles the views, and device memory may not hold all the bitmaps loaded all the time. Even Image loading Libraries face that issue.

Yes, there are performance issues with images in ListViews. But prefetching the images in any way is a could approach to avoid the calls to read operations on the file system and decoding of binary data. I extinguish that you are storing your viewholder in the convertviews - tag.

Loading images from disk is a slow operation, and so is decoding them from whatever compressed format they're stored in (like JPG or PNG) into a Bitmap. So ideally, it shouldn't be done in getView() on the main thread. Also, they take up a lot of memory.

If these "icons" are static, you should just include them as drawable resources and then use ImageView.setImageResource. Then the OS will figure out how to load them most optimally (plus, that way you'll have the correct resolution for the given screen).

If the icons are not static (eg loaded from the network), I recommend using an in-memory cache with an asynchronous loader, but make sure it's limited in size and/or uses weak references (but beware: Android generally advises against using weak/soft references, especially for bitmaps, since the memory allocated for bitmaps is in native code, so the garbage collector doesn't know how much memory those images are really taking up and it may decide not to collect them even if it's running low on memory... because it thinks they're small).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM