Why doesn't gravity work when applied to Relative Layout?

android, android-layout, android-relativelayout, xml

Solution

This is a supplemental answer to Gravity and layout_gravity on Android.

View `gravity` and `layout_gravity` inside a Relative Layout

My original statement that `gravity` and `layout_gravity` should not be used in the subviews of a `RelativeLayout` was partly wrong. The `gravity` actually works fine. However, `layout_gravity` has no effect. This can be seen in the example below. The light green and light blue are TextViews. The other two background colors are RelativeLayouts.

As you can see, `gravity` works, but `layout_gravity` doesn't work.

Relative Layout with `gravity`

My original answer about `gravity` and `layout_gravity` dealt with these attributes being applied to the Views within a `ViewGroup` (specifically a `LinearLayout`), not to the `ViewGroup` itself. However, it is possible to set `gravity` and `layout_gravity` on a `RelativeLayout`. The `layout_gravity` would affect how the `RelativeLayout` is positioned within its own parent, so I will not deal with that here. How `gravity` affects the subviews, though, is shown in the image below.

I resized the widths of all the subviews so that what is happening is more clear. Note that the way `RelativeLayout` handles gravity is to take all the subviews as a group and move them around the layout. This means that whichever view is widest will determine how everything else is positioned. So gravity in a Relative layout is probably only useful if all the subviews have the same width.

Linear Layout with `gravity`

When you add `gravity` to a `LinearLayout`, it does arrange the subviews as one would expect. For example, one could "save code" by setting the `gravity` of `LinearLayout` to `center_horizontally`. That way there is no need individually set the `layout_gravity` of each subview. See the various options in the image below.

Note that when a view uses `layout_gravity`, it overrides the LinearLayout's gravity. (This can be seen in the title for the two layouts in the left image. The LinearLayout `gravity` was set to `left` and `right`, but the title TextView's `layout_gravity` was set to `center_horizontally`.)

Final notes

When positioning views within a RelativeLayout, the general way to do it is adding things like the following to each view:

- `layout_alignParentTop`

- `layout_centerVertical`

- `layout_below`

- `layout_toRightOf`

If one wants to set all the views at once, a `LinearLayout` would likely be better (or perhaps using a Style).

So to sum up,

- The `layout_gravity` does not work for subviews in a RelativeLayout.

- The `gravity` of a RelativeLayout does work, but not as one might expect.

Supplemental XML

XML for image "View `gravity` and `layout_gravity` inside a Relative Layout":

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#e3e2ad" >

        <TextView
            android:id="@+id/tvTop1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:textSize="24sp"
            android:text="Views' gravity=" />

        <!-- examples of gravity -->
        
        <TextView
            android:id="@+id/tvTop2"
            android:layout_below="@id/tvTop1"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="left"
            android:text="left" />

        <TextView
            android:id="@+id/tvTop3"
            android:layout_below="@id/tvTop2"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center_horizontal"
            android:text="center_horizontal" />

        <TextView
            android:id="@+id/tvTop4"
            android:layout_below="@id/tvTop3"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="right"
            android:text="right" />

        <TextView
            android:id="@+id/tvTop5"
            android:layout_below="@id/tvTop4"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center"
            android:text="center" />

    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#d6c6cd" >

        <TextView
            android:id="@+id/tvBottom1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:textSize="24sp"
            android:text="Views' layout_gravity=" />

        <!-- examples of layout_gravity -->
        
        <TextView
            android:id="@+id/tvBottom2"
            android:layout_below="@id/tvBottom1"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="left"
            android:background="#bcf5b1"
            android:text="left" />

        <TextView
            android:id="@+id/tvBottom3"
            android:layout_below="@id/tvBottom2"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="center_horizontal"
            android:background="#aacaff"
            android:text="center_horizontal" />

        <TextView
            android:id="@+id/tvBottom4"
            android:layout_below="@id/tvBottom3"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="right"
            android:background="#bcf5b1"
            android:text="right" />

        <TextView
            android:id="@+id/tvBottom5"
            android:layout_below="@id/tvBottom4"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:background="#aacaff"
            android:text="center" />

    </RelativeLayout>

</LinearLayout>

XML for image "Relative Layout with gravity":

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center_horizontal"
        android:background="#e3e2ad" >

        <TextView
            android:id="@+id/tvTop1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:text="Views' gravity=" />

        <!-- examples of gravity -->

        <TextView
            android:id="@+id/tvTop2"
            android:layout_below="@id/tvTop1"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="left"
            android:text="left" />

        <TextView
            android:id="@+id/tvTop3"
            android:layout_below="@id/tvTop2"
            android:layout_width="300dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center_horizontal"
            android:text="center_horizontal" />

        <TextView
            android:id="@+id/tvTop4"
            android:layout_below="@id/tvTop3"
            android:layout_width="100dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="right"
            android:text="right" />

        <TextView
            android:id="@+id/tvTop5"
            android:layout_below="@id/tvTop4"
            android:layout_width="150dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center"
            android:text="center" />

    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:background="#d6c6cd" >

        <TextView
            android:id="@+id/tvBottom1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:text="Views' gravity=" />

        <!-- examples of layout_gravity -->

        <TextView
            android:id="@+id/tvBottom2"
            android:layout_below="@id/tvBottom1"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:gravity="left"
            android:background="#bcf5b1"
            android:text="left" />

        <TextView
            android:id="@+id/tvBottom3"
            android:layout_below="@id/tvBottom2"
            android:layout_width="300dp"
            android:layout_height="40dp"
            android:gravity="center_horizontal"
            android:background="#aacaff"
            android:text="center_horizontal" />

        <TextView
            android:id="@+id/tvBottom4"
            android:layout_below="@id/tvBottom3"
            android:layout_width="100dp"
            android:layout_height="40dp"
            android:gravity="right"
            android:background="#bcf5b1"
            android:text="right" />

        <TextView
            android:id="@+id/tvBottom5"
            android:layout_below="@id/tvBottom4"
            android:layout_width="150dp"
            android:layout_height="40dp"
            android:gravity="center"
            android:background="#aacaff"
            android:text="center" />

    </RelativeLayout>

</LinearLayout>

XML for image "Linear Layout with gravity":

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center_horizontal"
        android:background="#e3e2ad"
        android:orientation="vertical" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:textSize="24sp"
            android:text="View's gravity=" />

        <TextView
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="left"
            android:text="left" />

        <TextView
            android:layout_width="300dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center_horizontal"
            android:text="center_horizontal" />

        <TextView
            android:layout_width="100dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="right"
            android:text="right" />

        <TextView
            android:layout_width="150dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center"
            android:text="center" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:background="#d6c6cd"
        android:orientation="vertical" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:textSize="24sp"
            android:text="View's gravity=" />

        <TextView
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="left"
            android:text="left" />

        <TextView
            android:layout_width="300dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center_horizontal"
            android:text="center_horizontal" />

        <TextView
            android:layout_width="100dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="right"
            android:text="right" />

        <TextView
            android:layout_width="150dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center"
            android:text="center" />

    </LinearLayout>

</LinearLayout>

Problem

I already understand that if I use `layout_gravity="center_horizontal"` on the text view, then the text will be center. But I don't want to use that because I want to have as little code as possible and the best way to do that is by applying `gravity="center_horizontal"` to my relative layout. I am also asking this question because I am concerned about even using `gravity` or `layout_gravity` with relative layouts at all. As when doing my research I came upon this answer. Notice the part that says: Don't use gravity/layout_gravity with a RelativeLayout. Use them for Views in LinearLayouts and FrameLayouts. Even though it seems pretty apparent to me from the relative layout Android Documentation, which clearly lists `gravity` as a valid attribute, that Google intended these attributes to be used with relative layouts. If that quote is correct, how do I center views in relative layouts? Also, here is my code: Notice the title is not centered horizontally ``` <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:gravity="center_horizontal" tools:context="com.something"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.AppCompat.Title" android:textAlignment="center" android:text="@string/app_title" android:layout_marginBottom="@dimen/main_spacing" android:textSize="24sp" /> <AutoCompleteTextView android:id="@+id/enterContact" android:text="Enter Contact" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAlignment="center" android:layout_below="@+id/title" android:layout_marginBottom="@dimen/main_spacing" /> </RelativeLayout> ```

Original source

Related problems