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.

36 comments:

Michael said...

This blog post was very very informative. Thank you very much!

victory said...

This article is excellent!

Unknown said...

very very helpful blog.. cleared my many confusion..
Thanx a ton!! :)

NagPer said...

Thank you!! Very clear explanation!

Srikanth VM said...

This Article is Very Informative !!! Thanks for the nice article !

Unknown said...

Very nice article, helps explaining the concept very well!

Damian Flannery said...

Excellent, thank you!

PeEll said...

This is really helpful.

Any chance you could expand this to include dynamic-width elements, or aligning one item left, and another right within the same row?

Stefan Klumpp said...

Great visualization. Should help beginners a lot. Keep up the good work.

വിഷ്ണു ഹരിദാസ്‌ said...

This was a really helpful post. Thanks for the information.

Anonymous said...

Heh Sandip...this post is really really very helpful .
Thanks Dude!!!!!!!
keep it up :)

Anonymous said...

Heh Sandip...this post is really really very helpful .
Thanks Dude!!!!!!!
keep it up :)

Anonymous said...

Prashant :
This blog is amazing..Please tell me is there any change in using the layout for android 2.3.3

Dan said...

super clear explanation, no wonder it's on top of google search results. Thank you!

AlphaNerd said...

I can't tell you how helpful this was! I was just about to pull my hair out trying to arrange these UI elements. Great job, and please don't ever take this post down :D

- Derrick

Anonymous said...

THANKS..!

mobibob said...

Good explanation. Now can you do the same for the rest of the Dev Guide? :)

Beareema said...

Now i finally understand these things. Thank you so much! Really great blogpost!!

Anonymous said...

this is the good explanation to resolve the confusion between gravity and the layout_gravity

Psychotic Veggie said...

Thank you for your article, it helped me to resolve my issue and improve my understanding of Android.

Anonymous said...

great article on android:layout_gravity and android:gravity very informative

LIfe is crazyy said...

Thank you.

Unknown said...

Thanks Sandip

Anonymous said...

Well explained...it has resolved most of the doubt regarding gravity.

Hemant R. G. said...

Thanks. It is very helpful.

Meghna said...

Thanks for the brilliant example Man... Even this http://www.compiletimeerror.com/2013/06/android-linearlayout-example.html might help.. Have a look..

Chelsey said...

This is cool!

Anonymous said...

Excellent article !!

Anonymous said...

Nicely explained. Good job done.Thanks

Anonymous said...

Thanks for this value able documentation

Anonymous said...

"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."

Why doesn't that simple, precise statement exist anywhere else... even in the Android documentation itself. It clears up so much.

Thanks for the great article!

NoClues said...

Thanks for this great tutorial!!! It is very clear and easy to understand. Bookmarked!

Thank you very much!

Rutu said...

Very nice explanation of the Gravity Article.. Thanks

mbeu said...

Truly excellent tutorial - much appreciated!

Anonymous said...

Thank you, very nice having put a code that compile "as is" in Android, so we can try it out.
The explanation is very clear.

koshka said...

Very useful, thank you! :D