Fitting different sized images in GridView

0

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