3

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)

enter image description here

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

Gurg Hackpof
  • 1,304
  • 1
  • 13
  • 26

2 Answers2

1

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();
    }
}

enter image description here

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

Community
  • 1
  • 1
0

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>
tiny sunlight
  • 6,231
  • 3
  • 21
  • 42