RelativeLayout: align View centered horizontal or vertical relative to other view

40,466

Solution 1

Use a separate parent layout for those views and add it in your main layout(can contain other things if you have)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <LinearLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="vertical"
         android:gravity="center"
         android:layout_marginLeft = "30dp">
        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="dynamic text" />

        <TextView
            android:id="@+id/second"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="centered below text 1" />
    </LinearLayout>
...
...
other veiws go here
...

</RelativeLayout>

Solution 2

I have a much better solution than the accepted one. NO EXTRA NESTING! You can do this by combining two attributes on the smaller view. if you are centering horizontally you can use both align_start & align_end to the bigger view. Make sure the text gravity is centered btw "android:gravity="center". For Vertical alignment use both align_top & align_bottom. below is the modified implementation of your layout.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="43dp" >

<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignStart="@+id/second"
    android:layout_alignEnd="@+id/second"
    android:gravity="center"
    android:text="dynamic text" />

<TextView
    android:id="@+id/second"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/textView"
    android:gravity="center"
    android:text="centered below text 1" />

</RelativeLayout>

No need for unnecessary nesting like the accepted answer.

Solution 3

Use the followings which suits you

    android:layout_centerHorizontal="true"
    android:layout_centerInParent="true"    
    android:layout_centerVertical="true"    

Solution 4

Correct solution is to use ConstraintLayout

I tried to align a textview horizontally below a button in a RelativeLayout but it was not possible as align_bottom and layout_below didn't play well together. Finally i picked up constraintLayout and tried the same logic and it worked like a charm. here is the code below.

<android.support.constraint.ConstraintLayout 
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
xmlns:android="http://schemas.android.com/apk/res/android">

<Button
    android:id="@+id/episode_recording_header_stop"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@mipmap/ic_launcher"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.399" />


<TextView
    android:id="@+id/button_selected_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    android:textAlignment="center"
    android:textColor="@android:color/black"
    android:textSize="12sp"
    android:text="text which is exactly center aligned w.r.t the Button above"
    app:layout_constraintEnd_toEndOf="@+id/episode_recording_header_stop"
   app:layout_constraintStart_toStartOf="@+id/episode_recording_header_stop"
    app:layout_constraintTop_toBottomOf="@+id/episode_recording_header_stop" 
    />

</android.support.constraint.ConstraintLayout>

The final output is attached below

enter image description here

Solution 5

I found the solution: Wrap the content into another RelativeLayout and then you can place this LayoutWrapper wherever you want:

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

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="58dp"
        android:layout_marginTop="58dp" >

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerInParent="true"
            android:text="dynamic text" />

        <TextView
            android:id="@+id/second"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/textView"
            android:layout_centerInParent="true"
            android:text="centered below text 1" />
    </RelativeLayout>

</RelativeLayout>
Share:
40,466
sockeqwe
Author by

sockeqwe

Updated on March 14, 2020

Comments

  • sockeqwe
    sockeqwe over 4 years

    Is it possible to align a view in XML in a RelativeLayout centered horizontal or vertical according another already existing view.

    For example: lets say there is something like this:

    enter image description here

    The second text view should be displayed centered below the first text view:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="72dp"
            android:text="dynamic text" />
    
        <TextView
            android:id="@+id/second"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/textView"
            android:layout_marginLeft="43dp" <!-- Is there a rule to center it? -->
            android:text="centered below text 1" />
    
    </RelativeLayout>
    

    Is is possible to implement something like that in XML? Is there a rule that i have missed yet? I do not want to calculate the position programmatically

  • sockeqwe
    sockeqwe about 11 years
    No, i do not want to center it in parent ... I want to center it below or above a certain other view. For example: The other view has a marginLeft="72dp"
  • stinepike
    stinepike about 11 years
    yes just use centerhoarizontal=true and place that view above or below another
  • sockeqwe
    sockeqwe about 11 years
    Hm, maybe I get you wrong, but applying this centers the second text view in parent. But i want it to be centered below the other view, so centered relative according the first view is what i want ... I guess the that could be implemented by wrapping this two views in another RelativeLayout
  • sockeqwe
    sockeqwe about 11 years
    No, I do not want to center it in parent
  • stinepike
    stinepike about 11 years
    only use centerhorizontal .. i wrote all because I though you want to know how to center a view in a relativelayout.
  • sockeqwe
    sockeqwe about 11 years
    No, that center it horizontally in parent, but i want to center it relative to the first text view: i42.tinypic.com/2jkih.jpg
  • Noundla Sandeep
    Noundla Sandeep about 11 years
    That is not be the correct solution. Because, RelativeLayout is the heavy weight compare to LinearLayout. So we dont include on RL into another RL unless until we develop the complex UI. In your case it is little one so It is better to use LinearLayout.
  • sockeqwe
    sockeqwe over 9 years
    Yeah, but that only works if you know the width of the textview to adjust the margin.
  • Jessicardo
    Jessicardo over 9 years
    There is no need for margin.... The margin there is what you had initially. What happens is that the smaller text's width is mad equal to the larger text, and by having the gravity center, the view will be centered relative to the larger textview. To verify this, addjust the margin of the second textview or the contents of the text and watch the first one move as well.
  • Jessicardo
    Jessicardo over 9 years
    I have also removed the explicit margin, added padding to the layout container, and updated the layout.
  • Jessicardo
    Jessicardo over 9 years
    Sorry I had the wrong spelling of the attribute because I just typed it without an editor. Modified the code and tested and it works. I had it as "align_start" instead of "layout_align_start"
  • androidguy
    androidguy over 7 years
    Note that this is only useful if the text view doesn't have a background of its own that needs to be positioned just so, or a compound drawable on one of the sides on that axis.
  • Rakesh Gopathi
    Rakesh Gopathi over 6 years
    As you can see the alignment is w.r.t the anchor view (button) and not the parent or any other view.
  • sockeqwe
    sockeqwe over 6 years
    Yes, just use ConstraintLayout as it allows to do stuff like that (RelativeLayout doesn't) ...
  • Rakesh Gopathi
    Rakesh Gopathi over 6 years
    @sockeqwe The accepted answer doesn't answer the question right? Also it took me some time to realize that horizontal alignment of a view w.r.t another view is not possible in RelativeLayout. The correct answer is to use ConstraintLayout for now.
  • Ndifreke
    Ndifreke about 5 years
    This worked for me. Even when I manually set the width for the View, It always pulls the child relative to this parent to the center It seems to do the same thing ContraintLayout does