Fitting different sized images in GridView


There are 2 challenges here,
1) Fitting them so they look all made to fit
2) Using less memory as we do bitmap stuff

Bitmaps can bring challenges when you need to work with them across screens. Keeping the code neat and clear is also very important, for this you want to keep the layouts and fitting stuff in the xml, and the bitmap resizing, fitting, reading and memory handling in the code. Less code is good right ?

So I use a GridView and a layout to define the cell contents.

GridView will use attributes numColumns, gravity (once they fit, play with padding, margins, horizontalspacing and verticalspacing).

For the cell contents I use RelativeLayout (height = 0, weight = 1). ImageView within it uses scaleType=fitXY (play with the others once you have them all fitting) and layout_centerInParent.

In your getView of your GridAdapter, you need to set the width of your image at runtime. For this you need to get the screen width, and set the width of your image.


int w = getWindowManager().getDefaultDisplay().getWidth() ;
cellImage.setLayoutParams(new RelativeLayout.LayoutParams(
w/numOfColumnsInYourGridView, w/numOfColumnsInYourGridView));

This should do your fitting. Problem 1 solved.

Now reading the images will cause a lot of memory utilization (use DDMS Heap, to check it out), and a lot of GC. For this you should downsample your bitmaps as you read them.


private Bitmap getDownSampling(String resourceName) {
int maxSize = 125; // make 125 the upper limit on the bitmap size
Bitmap myBitmap ;
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true; // Only get the bitmap size, not the
// bitmap itself
try {
BitmapFactory.decodeStream(
getAssets().open("logos/" + resourceName), new Rect(10,
10, 10, 10), opts);
} catch (IOException e) {
e.printStackTrace();
}
int w = opts.outHeight, h = opts.outHeight;
int maxDim = (w > h) ? w : h; // Get the bigger dimension
int inSample = maxDim / maxSize;

opts = new BitmapFactory.Options();
opts.inSampleSize = inSample;

try {
myBitmap = BitmapFactory.decodeStream(
getAssets().open("logos/" + resourceName), new Rect(10,
10, 10, 10), opts);
} catch (IOException e) {
e.printStackTrace();
return null ;
}
return myBitmap;
}

This should use as little memory as needed.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s