Search code examples
androidxmlandroid-layoutandroid-linearlayoutandroid-relativelayout

Make child view group fill the rest of the parent group downwards


Consider the case of when one wants a View within a LinearLayout to fill out the rest of the empty space in the layout; one then sets the weight of this view to 1, while the weights of the others are 0.

Is there any way at all to do a similar thing with a child view group within a parent view group.

For example, consider my xml below:

<?xml version="1.0" encoding="utf-8"?>

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:fillViewport="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/coffee"
            android:scaleType="centerCrop"
            android:alpha="0.7"/>

        <TextView
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginBottom="16dp"
            android:gravity="center"
            android:text="@string/bus_title"
            android:textColor="#FFFF"
            android:textSize="24dp"
            android:textStyle="bold|italic" />

        <TextView
            android:id="@+id/about_heading"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/title"
            android:layout_marginBottom="16dp"
            android:gravity="center"
            android:text="About Us"
            android:textColor="#FFFF"
            android:textSize="16sp"
            android:textStyle="bold|italic" />

        <TextView
            android:id="@+id/about_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/about_heading"
            android:layout_marginBottom="16dp"
            android:gravity="center"
            android:text="@string/bus_description"
            android:textColor="#FFFF"
            android:textSize="16sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/opening_hours_header"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/about_text"
            android:layout_marginBottom="16dp"
            android:gravity="center"
            android:text="@string/opening_hours_header"
            android:textColor="#FFFF"
            android:textSize="16sp"
            android:textStyle="bold|italic" />

        <TextView
            android:id="@+id/opening_times"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/opening_hours_header"
            android:layout_marginBottom="16dp"
            android:gravity="center"
            android:text="@string/opening_hours"
            android:textColor="#FFFF"
            android:textSize="16sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/Contact_Us_heading"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/opening_times"
            android:layout_marginBottom="16dp"
            android:gravity="center"
            android:text="@string/Contact_heading"
            android:textColor="#FFFF"
            android:textSize="16sp"
            android:textStyle="bold|italic" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:orientation="vertical"
            android:layout_below="@id/Contact_Us_heading">

            <EditText
                android:id="@+id/email_field"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:background="#80E0E0E0"
                android:gravity="top"
                android:inputType="text"
                android:hint="Type a message here..."
                android:layout_below="@id/Contact_Us_heading"/>

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="end"
                android:text="SEND" />

        </LinearLayout>

    </RelativeLayout>

</ScrollView>

You'll see that below several textViews I insert a child LinearLayout.

I want the Linear Layout to fill the 'remaining space' downwards of the RelativeLayout, in the same way that the editText View fills the rest of the LinearLayout.

Is there any way to do that?


Solution

  • It's not possible with a RelativeLayout but you can convert it into a ConstraintLayout and use app:constraintVerticalWeight="1" to control the height of the main EditText component.

    In fact, you can do away with the nested LinearLayout entirely as ConstraintLayout can do it all for you in one go!

    The modified layout XML would look something like the following:

    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <ImageView
                android:id="@+id/imageView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:alpha="0.7"
                android:scaleType="centerCrop"
                android:src="@drawable/coffee" />
    
            <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:layout_marginBottom="16dp"
                android:gravity="center"
                android:text="@string/bus_title"
                android:textColor="#FFFF"
                android:textSize="24dp"
                android:textStyle="bold|italic"
                app:layout_constraintBottom_toTopOf="@+id/about_heading"
                app:layout_constraintTop_toTopOf="parent" />
    
            <TextView
                android:id="@+id/about_heading"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/title"
                android:layout_marginBottom="16dp"
                android:gravity="center"
                android:text="About Us"
                android:textColor="#FFFF"
                android:textSize="16sp"
                android:textStyle="bold|italic"
                app:layout_constraintBottom_toTopOf="@+id/about_text"
                app:layout_constraintTop_toBottomOf="@id/title"
                app:layout_constraintVertical_bias="0" />
    
            <TextView
                android:id="@+id/about_text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:gravity="center"
                android:text="@string/bus_description"
                android:textColor="#FFFF"
                android:textSize="16sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toTopOf="@+id/opening_hours_header"
                app:layout_constraintTop_toBottomOf="@+id/about_heading" />
    
            <TextView
                android:id="@+id/opening_hours_header"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:gravity="center"
                android:text="@string/opening_hours_header"
                android:textColor="#FFFF"
                android:textSize="16sp"
                android:textStyle="bold|italic"
                app:layout_constraintBottom_toTopOf="@+id/opening_times"
                app:layout_constraintTop_toBottomOf="@+id/about_text" />
    
            <TextView
                android:id="@+id/opening_times"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:gravity="center"
                android:text="@string/opening_hours"
                android:textColor="#FFFF"
                android:textSize="16sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toTopOf="@+id/Contact_Us_heading"
                app:layout_constraintTop_toBottomOf="@+id/opening_hours_header" />
    
            <TextView
                android:id="@+id/Contact_Us_heading"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:gravity="center"
                android:text="@string/Contact_heading"
                android:textColor="#FFFF"
                android:textSize="16sp"
                android:textStyle="bold|italic"
                app:layout_constraintBottom_toTopOf="@+id/email_field"
                app:layout_constraintTop_toBottomOf="@+id/opening_times" />
    
            <EditText
                android:id="@+id/email_field"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:background="#80E0E0E0"
                android:hint="Type a message here..."
                android:inputType="text"
                app:layout_constraintBottom_toTopOf="@+id/send_button"
                app:layout_constraintTop_toBottomOf="@id/Contact_Us_heading"
                app:layout_constraintVertical_weight="1" />
    
            <Button
                android:id="@+id/send_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="SEND"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toBottomOf="@id/email_field" />
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    
    </ScrollView>
    

    The resulting layout looks like this in the AndroidStudio UI designer (ignoring the missing string/drawable definitions, and noting I changed the text colour to black so that we could see the location of the text views):

    Example layout