android – RelativeLayout: align View centered horizontal or vertical relative to other view-ThrowExceptions

Exception or error:

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

How to solve:

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>

###

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.

###

Use the followings which suits you

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

###

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

###

Do this->

<?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_centerHorizontal="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_centerHorizontal="true" <!-- Is there a rule to center it? -->
        android:text="centered below text 1" />

</RelativeLayout>

###

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>

Leave a Reply

Your email address will not be published. Required fields are marked *