Search code examples
androidxmllayoutviewcenter

Android relative layout center horizontally with another view


I want to make some layout like this.

enter image description here Those views represents:

  • A is a message box.
  • B is a Profile picture
  • C is a description that should be on the right side of A & Center vertically with B

Some conditions are: - A should be above B & Center horizontally with B - Width of A is always greater than B - Height of C is always smaller than B - There shouldn't be a gap between B and C

If I put all three objects in a single container, I couldn't find a way to align A and B center horizontally. (layout_below puts B under A but aligned left)

I also tried to make a container including A and B, but if so, I cannot put C right after B (It causes a gap between B and C because A's width is greater than B).

Is there any way I can archive this only with XML layouts?


Solution

  • I personally think that it is impossible to reach what you want without an additional code from you.

    I could reach what you want by setting android:layout_marginLeft in View B. To keep the view centered with A, you must always set the margin by following formula:

    android:layout_marginLeft = ( (width_from_A / 4) + (width_from_B / 2) )
    

    In my example below, width_from_A == 200dp and width_from_B == 50dp

    So,

    android:layout_marginLeft = ( (200 / 4) + (50 / 2) )
    android:layout_marginLeft = ( 50 + 25 )
    android:layout_marginLeft = 75dp
    

    Java

    If your view does not always have same width, you can dynamically set the margins via Java code. This should work because in your activity, right before display the Layout to the user, you can get width from A and width from B and manually set the LeftMarging for B.

    @Override
    protected void onResume() {
    
        int widthA = findViewById(R.id.viewA).getLayoutParams().width;
        int widthB = findViewById(R.id.viewB).getLayoutParams().width;
    
        // THIS LINE JUST WORK FOR API>17
        ((RelativeLayout.LayoutParams)findViewById(R.id.viewB).getLayoutParams()).setMarginStart(widthA/4 + widthB/2);
    
        //FOR ANY API
        ((RelativeLayout.LayoutParams)findViewById(R.id.viewB).getLayoutParams()).setMargins(widthA/4 + widthB/2,0,0,0);
    
        super.onResume();
    }
    

    Layout

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <TextView
            android:id="@+id/viewA"
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:gravity="center"
            android:text="A"
            android:background="@android:color/holo_blue_dark"/>
    
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/viewA">
    
            <TextView
                android:id="@+id/viewB"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:gravity="center"
                android:text="B"
                android:layout_marginLeft="75dp"
                android:background="@android:color/holo_green_dark"/>
    
    
            <TextView
                android:id="@+id/viewC"
                android:layout_width="150dp"
                android:layout_height="50dp"
                android:gravity="center"
                android:text="C"
                android:layout_toRightOf="@+id/viewB"
                android:background="@android:color/holo_red_dark"/>
        </RelativeLayout>
    </RelativeLayout>
    

    Result

    enter image description here