Search code examples
androidimageviewandroid-imageviewimagebutton

40+ ImageButtons on one screen?


For last 10+ hours I try to get a large (40+) amount of images (in ImageButton format) on a single Android screen without out of memory errors. The activity I work on is an image picker for a coloring book app. Images are of various sizes in the range of (500 to 1200)x(500 to 1200), PNGs (if that matters).

I have tried:

  • Horizontal Scroll View with images added from the code. The result is slow (I do it on UI thread) and consumes large memory space.
  • Horizontal Scroll View with images added from the code via AsyncThread. The result is fast but still consumes large memory space. I like the user experience of this one the most!
  • Grid View and List View - both are very choppy (testing on first Nexus 7). Memory usage is better.

What I am considering

  • View Pager - first results look better than Grid View from performance perspective (I have not completed it to the moment to assess the memory usage but it should be better from what I understand). Yet, I dislike the user experience and prefer a scrollable list of all images.
  • Conversion of my resources to JPG (will that get rid of Transparency byte?)
  • Downsizing the images to max 500x500px

None of the solutions seems as good as the Android Photo Gallery app available on all devices. This experience is what I would love to mirror. No idea how this is done though :(

Two questions.

  1. What is the best way to get such thing (40+ Images scrollable on single screen) done? Is it really ViewPager? ScrollView with AsyncTask and well thought images resolution? Something I have not tried yet?
  2. What is the memory limit I should try to keep below? Looking at Android heap size on different phones/devices and OS versions it seems to be 256 MB, is that fair assumption?

Thanks. Have a great weekend!

PS. On iOS all works like charm when I add all the buttons into a scroll view :(


Solution

  • Some basic calculations reveals your problem:

    40+ images at 1200x1200 = approx 57MB, the comments are correct you need to subsample (i.e. thumbnail) the images or use a library such as the Universal Image Loader. Converting to JPG doesn't matter. That is a compressed storage format, the memory required to display the pixels remains the same.

    There is a Android Developers article on Loading Large Bitmaps Efficiently with sample code. The following steps are covered in more detail in the article Android Bitmap Loading for Efficient Memory Usage.

    The basic steps in loading a large bitmap are:

    • Determine the required size (from a known size or determining the size of the target View).
    • Use the BitmapFactory class to get the bitmap’s size (set inJustDecodeBounds in BitmapFactory.Options to true).
    • Calculate the subsampling value and pass it to the BitmapFactory.Options setting inSampleSize.
    • Use the BitmapFactory to load a reduced size bitmap.