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

unable to stretch rows in tablelayout, like stretchcolumns

0

This worked, after I used weightSum and weight parameters.

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" android:layout_height="fill_parent"
	android:orientation="vertical" android:layout_gravity="bottom|top"
	android:background="@drawable/homescreenback" android:weightSum="4"
	android:paddingLeft="20px">
	<TableRow android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:layout_weight="1">
		<Button android:id="@+id/shop1" android:text="@string/shop1"
			android:layout_gravity="left|center" android:layout_width="wrap_content"
			android:layout_height="wrap_content" android:background="@drawable/icon" />
	</TableRow>
	<TableRow android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:layout_weight="1">
		<Button android:id="@+id/shop2" android:text="@string/shop2"
			android:layout_gravity="left|center" android:layout_width="wrap_content"
			android:layout_height="wrap_content" android:background="@drawable/icon" />
	</TableRow>
	<TableRow android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:layout_weight="1">
		<Button android:id="@+id/shop3" android:text="@string/shop3"
			android:layout_gravity="left|center" android:layout_width="wrap_content"
			android:layout_height="wrap_content" android:background="@drawable/icon" />
	</TableRow>
	<TableRow android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:layout_weight="1">
		<Button android:id="@+id/shop4" android:text="@string/shop4"
			android:layout_gravity="left|center" android:layout_width="wrap_content"
			android:layout_height="wrap_content" android:background="@drawable/icon" />
	</TableRow>

</TableLayout>

Android Relative Layout basics

1

Relative Layout, as the name suggests you can place widgets relative to other widgets. The widget ID is used to refer to it. To refer to a ID, it should be defined earlier than it is used, since the parsing of the xml file is top to bottom. From 1.6 its not needed to declare the widget id before its used (http://android-developers.blogspot.com/2009/10/ui-framework-changes-in-android-16.html). I guess from 1.6 they now double parse the xml file.

This blog post will (hopefully) make it easy for you to understand this layout. The widgets are placed relative to already defined ones. You can place widgets using any or all of the 3 (at a high level) relations.

1) Where to place the widget “within” the parent ? In other words, align the widget to which wall of the parent.

layout_alignParentRight – Will stick the widget to the inner right wall of the parent
layout_alignParentLeft – Will stick the widget to the innerleft wall of the parent
layout_alignParentTop – Will stick the widget to the inner top wall of the parent
layout_alignParentBottom – Will stick the widget to the inner bottom wall of the parent

2) Where to place this widget in relation to “another” widget (already defined). Specifying one of the below parameters will place the widget outside (obviously since the widget is not the parent) the relative widget

layout_bottom – Will stick the widget top wall, to the outer bottom wall of the relative
layout_top – Will stick the widget bottom wall, to the outer top wall of the relative
layout_toRight  – Will stick the widget left wall, to the outer right wall of the relative
layout_toLeft – Will stick the widget right wall, to the outer left wall of the relative

3) Where to place this widget in relation to “another” widget (already defined). Specifying one of the below parameters will place the widget outside (obviously since the widget is not the parent) the relative. These parameters are a bit different as compared to the ones explained in 2). This tells the widget to align with a wall of the relative, not stick to it.  Now, this parameter should be used in conjunction with other parameters for sake of clarity in code. As you read thru you will understand why.

layout_alignBottom – Will stick (or may not) the widget left / right wall, to the right / left wall of the relative, and align the bottom walls of both widgets. Kinda like keeping 2 objects on a dining table. Both share the same bottom alignment.
layout_alignTop – Will stick (or may not) the widget left / right wall, to the right / left wall of the relative, and align the top walls of both widgets. Kinda like keeping 2 objects suspended from the roof with ropes of same length. Both share the same top alignment.
layout_alignRight  – Will stick (or may not) the widget top / bottom wall, to the bottom / top wall of the relative, and align the right walls of both widgets. Kinda like keeping 2 objects one above another stuck to the same wall. Both share the same right alignment.
layout_alignLeft – Will stick (or may not) the widget top / bottom wall, to the bottom / top wall of the relative, and align the left walls of both widgets. Kinda like keeping 2 objects one above another stuck to the same wall. Both share the same left alignment.

4) Special Alignments – Where to place the widget within the parent. To center is horizontally, vertical or bang on center (both vertical and horizontal).

layout_centerHorizontal, layout_centerVertical, layout_centerInParent

I cant explain everything to you :). Your homework, explain layout_alignBaseline to me and others.