Tuesday, May 11, 2010

LinearLayout gravity and layout_gravity explained

Recently I started hacking on Android. Android uses Java as the development language which made it very easy to get started :) .

I am very familiar with Swing and SWT GUI layout mechanism of Layout Managers and Layouts respectively. I was happy to find out that Android also uses a notion of View Groups which are analogous to the Layout Managers. The Android supports several View Groups, LinearLayout, RelativeLayout to name a few. There many more.

The Android View Groups employ a notion of LayoutParams that are analogous to layout constraints used by Swing Layout Managers. The LayoutParams configure the way the Android View Group lays out it's children views. In Android the GUI can be either built programmatically using Java code or using an XML file. The structure of the XML elements parallels the structure of View object you may build programatically. The XML attributes are used to configure the Layout Params.

LinearLayout

The LinearLayout is a commonly used View Group that lays out it's children views either horizontally or vertically. More details of LinearLayout read this.

android:gravity and android:layout_gravity

After reading the documentation I set out to use the Linear Layout and I came across the the following layout params:
  • android:gravity
  • android:layout_gravity
I must say that my initial experience was a little frustrating. Based on the documentation it was not very clear how the above layout parameters work. After a little bit of googling I soon found out that many people have run into this. So I dove in to find out more details and finally understood how to use these layout parameters with Linear Layout. I will explain using an example layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" android:background="#666666">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="Linear Layout - horizontal, gravity=center"
android:textColor="#FFFFFF" android:padding="2dip" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:orientation="horizontal"
android:layout_height="0dip" android:layout_weight="1"
android:gravity="center" android:background="#EEEEEE">

<Button android:id="@+id/Button01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="top"
android:text="top"></Button>
<Button android:id="@+id/Button02" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="center"
android:text="center"></Button>
<Button android:id="@+id/Button03" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="bottom"
android:layout_gravity="bottom"></Button>
</LinearLayout>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="Linear Layout - vertical, gravity=center"
android:textColor="#FFFFFF" android:padding="2dip" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:orientation="vertical"
android:layout_height="0dip" android:layout_weight="1"
android:gravity="center" android:background="#DDDDDD">

<Button android:id="@+id/Button04" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="left"
android:text="left"></Button>
<Button android:id="@+id/Button05" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="center"
android:text="center"></Button>
<Button android:id="@+id/Button06" android:layout_height="wrap_content"
android:text="right" android:layout_gravity="right"
android:layout_width="wrap_content"></Button>
</LinearLayout>
</LinearLayout>
This results in the following layout:


android:gravity attribute

Strictly speaking android:gravity is not a Layout Param. The android:gravity is really an attribute of the View Group. It controls the way the contents of the View Group will be positioned horizontally and vertically.

In the above example the top Linear Layout is a horizontal Linear Layout. So setting the android:gravity=center has an effect of positioning the set of buttons in the horizontal center.

In the above example the bottom Linear Layout is a vertical Linear Layout. So setting the android:gravity=center has an effect of positioning the set of buttons in the vertical center.

android:layout_gravity Layout Param

The android:layout_gravity is a Layout Param. Not all View Groups support this Layout Param. See the documentation to find out which Layout Params are supported by a particular View Group. Linear Layout does support android:layout_gravity Layout Param.

For a horizontal Linear Layout the following values make sense:
  • top
  • center
  • bottom
That is because the children of a horizontal Linear Layout are layed out horizontally one after the other. Only thing can be controlled using the android:layout_gravity is how a child view is positioned vertically.

In the above example the top Linear Layout is a horizontal Linear Layout. Setting the android:layout_gravity=top on the l_g=top Button has an effect of positioning it at the top. Setting the android:layout_gravity=center on the l_g=center Button has an effect of positioning it at the vertical center. Setting the android:layout_gravity=bottom on the l_g=bottom Button has an effect of positioning it at the bottom.

For a vertical Linear Layout the following values make sense:
  • left
  • center
  • right
That is because the children of a vertical Linear Layout are layed out vertically one below the other. Only thing can be controlled using the android:layout_gravity is how a child view is positioned horizontally.

In the about example the bottom Linear Layout is a vertical Linear Layout. Setting the android:layout_gravity=left on the l_g=left Button has an effect of positioning it at the left. Setting the android:layout_gravity=center on the l_g=center Button has an effect of positioning it at the horizontal center. Setting the android:layout_gravity=right on the l_g=right Button has an effect of positioning it at the right.