简体   繁体   中英

Aligning the vertical center of a view to the top of another view

It seems fairly simple, but I can seem to figure out to produce xml that achieves the following result: (lots of interesting content on SO, but surprisingly, I found nothing that answers that one)

在此输入图像描述

The black view is the outer-frame, the blue view is aligned to the bottom and the red view's vertical center is aligned to the top of the blue view.

Constraints:

  • don't assume red view has a fixed size (to compute the half of it for an offset margin),
  • don't do it programmatically, xml rulez

edit: fixed the messed-up description and added the constraints

If the float view has fixed size.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/a"
        android:layout_alignParentBottom="true"
        android:background="#44bb11"
        android:layout_width="match_parent"
        android:layout_height="100dp" />
    <ImageView
        android:layout_marginBottom="-40dp"
        android:layout_above="@+id/a"
        android:id="@+id/c"
        android:background="#45000000"
        android:layout_width="match_parent"
        android:layout_height="80dp" />
</RelativeLayout>

If you cannot count on having a fixed height, then the margin will need to be determined at runtime, when the height is determined. Otherwise you hard code a bottom margin that is a negative value of half the layout height (of the blue layout). I have provided two nested layouts to use within your main activity layout.

I've used a button in this particular case to test the app, you can implement it in any way you choose. The order with which you add the layouts to the xml will affect the visibility of them. It's important to place the one you want to be on top last.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout ../..
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/black"
            tools:showIn="@layout/activity_main">

    <RelativeLayout android:id="@+id/l1"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_alignParentBottom="true"
        android:background="@android:color/holo_blue_light"/>

    <RelativeLayout android:id="@+id/l2"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_above="@+id/l1"
        android:background="@android:color/holo_red_light"/>
</RelativeLayout>

I borrowed a method from this answer here :

public void setMargin(View view) {
    if (relativeLayout
            .getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams marginLayoutParams =
                (ViewGroup.MarginLayoutParams) relativeLayout
                        .getLayoutParams();
        int margin = relativeLayout.getHeight() / 2;
        marginLayoutParams.setMargins(20, 0, 0, -margin);
        relativeLayout.requestLayout();
    }
}

在此输入图像描述

For the purposes of demonstration I've pushed margins on either side of the two layouts, so you can see where they're overlapping.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM