androidandroid-layoutandroid-relativelayoutandroid-percentrelativelayout

Controlling nested ViewGroup size in a RelativeLayout: with wrap_content is still matching parent


I have a widget that uses PercentRelativeLayout to position 4 ImageViews inside it. I need the percent feature because I’m putting the images along the 4 sides of the box but with different relative sizes: the top child takes up ~60 percent of the height. I have previewed this layout by itself and it works great, no problem. This widget does wrap_content for w and h (w I don’t care about so much, but h is important, as you will see.)

I need this widget inside a larger layout. Now I have another parent RelativeLayout. This layout should contain the described widget at the top, then some buttons below it, in a mostly linear fashion: |--(group widget)--(text button)--(image button)—-|, where the ‘|’ indicates it should be snug to the parent. (The reason this is a Relative is that I want to float another view at the bottom right.)

So the goal is: this parent layout should be sized to some predefined size (basically the screen, although in my full code there is more above this level as well - but my problem occurs just isolating at this level), the 2 buttons should calculate their natural size and use it, then the PercentRelativeLayout at the top should take the ‘remaining’ height and use that for its children % sizing.

In practice, as the screenshot shows (from the layout preview tool) - the PercentRelativeLayout sucks up all the size.

In short, can you pin together a sequence of views in a relative layout and have a variable child? In iOS I would pin the first view to the parent top, the last view to the parent bottom, and everything to the thing above it, the buttons have their intrinsic size and then my mystery widget sucks up the remainder.

<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#f2dce8ff"
android:layout_marginTop="8dp"
xmlns:android="http://schemas.android.com/apk/res/android">

<android.support.percent.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    xmlns:tools="http://schemas.android.com/tools"
    android:animateLayoutChanges="true"
    android:id="@+id/matchPlay">

    <ImageView
        android:src="@drawable/model_2"
        tools:background="#954f47"
        app:layout_heightPercent="59%"
        app:layout_aspectRatio="100%"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:adjustViewBounds="false"
        android:id="@+id/avatarView1"
        android:scaleType="centerInside" />
    <ImageView
        android:src="@drawable/model_2"
        tools:background="#ff0000"
        app:layout_heightPercent="20%"
        app:layout_aspectRatio="100%"
        app:layout_marginTopPercent="2%"
        android:layout_below="@id/avatarView1"
        android:layout_alignParentLeft="true"
        android:adjustViewBounds="false"
        android:id="@+id/avatarView2"
        android:scaleType="centerCrop" />
    <ImageView
        android:src="@drawable/model_2"
        tools:background="#00ff00"
        app:layout_heightPercent="20%"
        app:layout_aspectRatio="100%"
        app:layout_marginTopPercent="2%"
        android:layout_below="@id/avatarView1"
        android:layout_alignParentRight="true"
        android:adjustViewBounds="false"
        android:id="@+id/avatarView3"
        android:scaleType="centerCrop" />
    <ImageView
        android:src="@drawable/model_2"
        tools:background="#0000ff"
        app:layout_heightPercent="22%"
        app:layout_aspectRatio="100%"
        android:layout_below="@id/avatarView2"
        android:layout_centerHorizontal="true"
        android:adjustViewBounds="false"
        android:id="@+id/avatarView4"
        android:scaleType="centerCrop" />

</android.support.percent.PercentRelativeLayout>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/matchplay_add_shout"
    android:id="@+id/shoutButton"
    android:enabled="false"
    android:layout_centerHorizontal="true"
    android:layout_below="@id/matchPlay" />

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/submitButton"
    android:src="@drawable/matchplay_submit"
    android:layout_centerHorizontal="true"
    android:layout_below="@id/shoutButton"
    android:minWidth="50dp"
    android:contentDescription="@string/matchplay_send_contentdesc" />

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/passButton"
    android:src="@drawable/matchplay_pass"
    android:layout_alignParentEnd="true"
    android:layout_alignParentBottom="true"
    android:contentDescription="@string/matchplay_pass_contentdesc" />

Edit: I updated this code to not use alignParentBottom, thinking that was the key issue; I instead used alignParentTop. No change. ALso tried using vertical LinearLayout at the root. :(

enter image description here By the way the image group widget will be a PercentRelativeLayout subclass, so if I need to make some magic happen with some overrides there, I can do that.


Solution

  • I learned some things about the RelativeLayout beast:

    Thus I just made the dependencies backward, where things were pinned to the bottom, thus matchPlay was last in the dependency chain. The strange but functioning XML is below. Very strange aspect of implementation, and further the documentation does not state this lack of associativity in the relative layout_ attrs. (Clearly it should, because it can greatly affect how you use the relative attrs!)

    <RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#f2dce8ff"
    android:layout_marginTop="8dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
    
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/matchplay_add_shout"
        android:id="@+id/shoutButton"
        android:layout_above="@+id/submitButton"
        android:layout_marginTop="15dp"
        android:layout_centerHorizontal="true"
        android:enabled="false" />
    
    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/submitButton"
        android:src="@drawable/matchplay_submit"
        android:minWidth="50dp"
        android:contentDescription="@string/matchplay_send_contentdesc" />
    
    <android.support.percent.PercentRelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/shoutButton"
        xmlns:tools="http://schemas.android.com/tools"
        android:animateLayoutChanges="true"
        android:id="@+id/matchPlay">
    
        <ImageView
            android:src="@drawable/model_2"
            tools:background="#954f47"
            app:layout_heightPercent="60%"
            app:layout_aspectRatio="100%"
            app:layout_marginBottomPercent="2%"
            android:layout_centerHorizontal="true"
            android:adjustViewBounds="false"
            android:id="@+id/avatarView1"
            android:scaleType="centerInside" />
        <ImageView
            android:src="@drawable/model_2"
            tools:background="#ff0000"
            app:layout_heightPercent="23%"
            app:layout_aspectRatio="100%"
            android:layout_below="@id/avatarView1"
            android:adjustViewBounds="false"
            android:id="@+id/avatarView2"
            android:scaleType="centerCrop" />
        <ImageView
            android:src="@drawable/model_2"
            tools:background="#00ff00"
            app:layout_heightPercent="23%"
            app:layout_aspectRatio="100%"
            android:layout_below="@id/avatarView1"
            android:layout_alignParentRight="true"
            android:adjustViewBounds="false"
            android:id="@+id/avatarView3"
            android:scaleType="centerCrop" />
        <ImageView
            android:src="@drawable/model_2"
            tools:background="#0000ff"
            app:layout_heightPercent="23%"
            app:layout_aspectRatio="100%"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:adjustViewBounds="false"
            android:id="@+id/avatarView4"
            android:scaleType="centerCrop" />
    
    </android.support.percent.PercentRelativeLayout>
    
        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/passButton"
            android:src="@drawable/matchplay_pass"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            android:contentDescription="@string/matchplay_pass_contentdesc" />