DEMO 04

Gravity and layout_gravity

Two attributes, almost the same name, completely different jobs. Click the same square on both sides and watch which one moves.

What to do

Click bottom end on both sides. On the left the words move; on the right the button moves. Same value, different target.

Then askWhich of the two needs a parent that is bigger than the view?

Only one of them can do anything at all if the view is already filling its parent. That is the giveaway.

android:gravity

android:gravity="top|start"

Where the contents sit inside this view. The view itself never moves — only the text inside it does.

Content this is inside the view

android:layout_gravity

android:layout_gravity="top|start"

Where this view sits inside its parent. The contents stay put — the whole box moves.

Button this is the view
activity_main.xml — the two attributes side by side
<!-- the parent decides where its children go -->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- gravity: aligns the TEXT inside this TextView -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="top|start"
        android:text="Content" />

    <!-- layout_gravity: aligns THIS BUTTON inside its parent -->
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top|start"
        android:text="Button" />

</LinearLayout>
The rule gravity is about the inside. layout_gravity is about the outside. The layout_ prefix always means “my position inside my parent” — that is true of layout_width, layout_margin and layout_weight too.

Stacking instead of lining up

Linear and Relative lay views out side by side. A FrameLayout puts them on top of each other, in the order you write them — the last one wins.

Then askWhich view is drawn on top?
A mechanical stopwatch on a wooden panel
Text on top of an image
Both children of the same FrameLayout — the TextView is written second, so it draws last.

Photo Anton Makarenko · Pexels #1078057

activity_main.xml — the order of children is the z-order
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- drawn first: bottom of the stack -->
    <ImageView
        android:src="@drawable/stopwatch"
        android:scaleType="centerCrop" />

    <!-- drawn second: on top -->
    <TextView
        android:layout_gravity="bottom|start"
        android:text="Text on top of an image" />

</FrameLayout>
A grid of white boxes, one knocked out of alignment

Photo Dalila Dalprat · Pexels #10938208 · every box sits in its parent. Move one and only one moves — that is layout_gravity.

Because there is no spare room to move into.

If a view already fills its parent — layout_width="match_parent" and layout_height="match_parent" — then layout_gravity has nothing to do. The view occupies every available pixel, so “bottom” and “top” describe the same rectangle.

That is the single most common reason a student's centring “just does not work”: the four attributes are fighting each other. Try it on the right-hand panel above — set the box to match_parent in both directions and watch the position picker stop having any effect.

The mental test: gravity is pointless if the contents already fill the view; layout_gravity is pointless if the view already fills the parent.