Seva Alekseyev
Seva Alekseyev

Reputation: 61370

Make a view take the rest of available space, if any

I'm trying to implement a layout in Android with the following display logic:

[ Left ][ Right ]
[    Bottom     ]

Where Left is sometimes wider than Bottom, sometimes narrower. When Bottom is wider than Left, I want Right to extend all the way to Bottom's right edge; when Left is wider, I want the Right to be 0px wide.

The nature of Left and Bottom isn't that important; they both are wrap_content ones.

I've tried with LinearLayout and RelativeLayout on the top level. No matter what I do, either the width of the outermost container is driven by Bottom with no respect to Left, or the view extends unreasonably, or the Right is always zero-width.

Here's my latest attempt with RelativeLayout:

<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="78dp"
    >

    <TextView
         android:id="@+id/Left"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="Left"/>

    <View
        android:id="@+id/Right"
        android:layout_width="0dp"
        android:layout_toRightOf="@+id/Left"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_height="1px"
        android:layout_marginTop="32dp"
        android:background="#ffffffff"/>

    <TextView
        android:id="@+id/Bottom"
        android:layout_width="wrap_content"
        android:layout_height="23dp"
        android:layout_below="@+id/Left"
        android:layout_alignParentLeft="true"
        android:textColor="#ffff00"
        android:text="Hello"
        android:lines="1"/>
</RelativeLayout>

It doesn't work as expected; the Right view is stretched out unreasonably.

Testing on 4.4.2 emulator. The whole thing is inside a ScrollView, if it matters. Target SDK is 17.

Upvotes: 0

Views: 96

Answers (2)

MysticMagicϡ
MysticMagicϡ

Reputation: 28823

If I understood your question correctly, then may be this should work:

I put Left and Right in a parent layout, and put the other textview below that parent container. Set height accordingly.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="78dp"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.tempp.MainActivity" >

    <RelativeLayout
        android:id="@+id/upper"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/Left"
            android:layout_width="wrap_content"
            android:layout_height="32dp"
            android:text="Here I have written some text which is long" />

        <View
            android:id="@+id/Right"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_alignParentTop="true"
            android:layout_marginTop="32dp"
            android:layout_toRightOf="@+id/Left"
            android:background="#000000" />
    </RelativeLayout>

    <TextView
        android:id="@+id/Bottom"
        android:layout_width="wrap_content"
        android:layout_height="23dp"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/upper"
        android:lines="1"
        android:text="Hello"
        android:textColor="#ffff00" />

</RelativeLayout>

From this I get following outputs:

First case: (with a short text in Left TextView)

enter image description here

Second case: (with a long text for Left TextView but text is contained in a single line)

enter image description here

Third case: (With the text which exceeds 1 line)

enter image description here

Hope this helps.

P.S: The text of textview in second line is cut a bit due to outer layout's height, which I kept as it was in your question.

EDIT:

This is the output while the text in second line is longer than text in first line.

enter image description here

Upvotes: 1

ycagri
ycagri

Reputation: 434

I think a custom view can solve your problem. I changed your layout a little bit and wrapped inside a custom relative layout. I checked widths of children OnLayout event of custom relative layout. If left is wider than bottom, right doesn't change. Otherwise, width of right is set to width difference. A boolean is kept for doing this operation only once. Otherwise, change in layout causes recursive call to OnLayout method.

Here is custom class:

public class CustomRelativeLayout extends RelativeLayout {

private boolean mIsLayoutSet = false;

public CustomRelativeLayout(Context context) {
    super(context);
}

public CustomRelativeLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);

    if (!mIsLayoutSet) {
        View left = findViewById(R.id.Left);
        View right = findViewById(R.id.Right);
        View bottom = findViewById(R.id.Bottom);

        int leftWidth = left.getWidth();
        int bottomWidth = bottom.getWidth();

        if (bottomWidth > leftWidth) {
            LayoutParams params = (LayoutParams) right.getLayoutParams();
            params.width = bottomWidth - leftWidth;
            right.setLayoutParams(params);
        }

        mIsLayoutSet = true;
    }
}

}

and the usage of custom layout:

<com.rotasoftc.myapps.CustomRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
    android:id="@+id/Left"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Left"/>

<View
    android:id="@+id/Right"
    android:layout_width="0dp"
    android:layout_toRightOf="@+id/Left"
    android:layout_height="15px"
    android:background="@android:color/black"
    android:layout_marginTop="7dp"/>

<TextView
    android:id="@+id/Bottom"
    android:layout_width="wrap_content"
    android:layout_height="23dp"
    android:layout_below="@+id/Left"
    android:layout_alignParentLeft="true"
    android:textColor="#ffff00"
    android:text="HelloHelloHelloHello"
    android:lines="1"/>
</com.rotasoftc.myapps.CustomRelativeLayout>

Upvotes: 0

Related Questions