sockeqwe
sockeqwe

Reputation: 15929

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

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

Upvotes: 21

Views: 42688

Answers (7)

Sergey V.
Sergey V.

Reputation: 1028

If you need to use RelativeLayout please don't use the nested layouts as far as possible. Today we have many other efficient cases to solve your task. But with use of the old faithful RelativeLayout the better way is to use attributes android:layout_alignTop, android:layout_alignBottom and android:gravity. For example, you would like to align TextView according to EditText vertically.

<RelativeLayout ...>
        ...
        <TextView
                android:id="@+id/tv1"
                ...
                android:gravity="center"
                android:layout_alignTop="@+id/edt1"
                android:layout_alignBottom="@id/edt1"/>
        <EditText
                android:id="@+id/edt1"
                ... 
                android:layout_toRightOf="@id/tv1"/>
</RelativeLayout>

enter image description here

In the same way you can use android:layout_alignLeft, android:layout_alignRight and android:gravity or android:layout_alignStart, android:layout_alignEnd and android:gravity horizontally.

Upvotes: 0

Sandeep
Sandeep

Reputation: 3344

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>

Upvotes: 18

Rakesh Gopathi
Rakesh Gopathi

Reputation: 303

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

Upvotes: 3

Jessicardo
Jessicardo

Reputation: 869

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.

Upvotes: 36

sockeqwe
sockeqwe

Reputation: 15929

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>

Upvotes: 1

Vishal Pawale
Vishal Pawale

Reputation: 3476

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>

Upvotes: 1

stinepike
stinepike

Reputation: 54682

Use the followings which suits you

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

Upvotes: 12

Related Questions