[FIXED] GridLayout with variable row height in Xamarin

Issue

I have a fairly simple Xamarin app with a primary interface that consists of two ImageViews, one overlayed on the other. The images are the same size, and I want them to expand to fill the screen. Except that I want the bottom 100 pixels (about) reserved for a banner ad.

Without the ad, I found this simple. I used a RelativeLayout, set the layout_height and layout_width to match_parent, put both images in it, and set layout_CenterInParent to true for both of them. It works great.

And then I went to put the banner in. I tried using a GridLayout with one column and two rows, putting the prior RelativeLayout inside the top cell and the banner inside the bottom cell. But unless I restrict the height of the RelativeLayout to a fixed height, it expands until the banner is invisible. And I don’t want to restrict it to a fixed height, because I want to expand it to the full height minus the banner height.

I realize that there’s a basic contradiction between filling a space and restricting the height, but I’m hoping that there’s some solution for this.

In css, I can use heights like wh-100 to be the full window height minus 100 pixels. Is there anything similar in Xamarin? Failing that, is there any trick I can use to achieve what I’m trying to do?

<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="2"
android:columnCount="1"
android:id="@+id/gridLayout1">
<RelativeLayout
    android:minWidth="25px"
    android:minHeight="25px"
    android:id="@+id/relativeLayout1"
    android:layout_width="wrap_content"
    android:layout_height="400px"
    android:layout_rowWeight="1"
    android:background="#ffff44">

    <ImageView
        android:id="@+id/img1"
        android:src="@drawable/img1"
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    <ImageView
        android:id="@+id/img2"
        android:src="@drawable/img2"
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</RelativeLayout>

<RelativeLayout
    android:minWidth="100px"
    android:minHeight="100px"
    android:layout_height="100px"
    android:id="@+id/relativeLayout2"
    android:layout_width="wrap_content"
    android:background="#ccff44">
    <ImageView
        android:id="@+id/banner_placeholder"
        android:src="@drawable/banner_placeholder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</RelativeLayout>

Thanks for any help.

Solution

At first, if you use the GridLayout , you can set the control’s height as the parent’s – 100 in the xml. But you can use the row height to set the control’s height such as:

<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="2"
android:columnCount="1"
android:id="@+id/gridLayout1">
<RelativeLayout
    android:minWidth="25px"
    android:minHeight="25px"
    android:id="@+id/relativeLayout1"
    android:layout_width="wrap_content"
    android:layout_height="400px"
    android:layout_row="0"
    android:layout_rowWeight="3"
    android:background="#ffff44">

    <ImageView
        android:id="@+id/img1"
        android:src="@drawable/img1"
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    <ImageView
        android:id="@+id/img2"
        android:src="@drawable/img2"
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</RelativeLayout>

<RelativeLayout
    android:minWidth="100px"
    android:minHeight="100px"
    android:layout_height="100px"
    android:layout_row = "1"
    android:layout_rowWeight="3"
    android:id="@+id/relativeLayout2"
    android:layout_width="wrap_content"
    android:background="#ccff44">
    <ImageView
        android:id="@+id/banner_placeholder"
        android:src="@drawable/banner_placeholder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</RelativeLayout>

This will set the first RelativeLayout’s height as 3/4 of the parent and the second as the 1/4.

If you still want to set the first RelativeLayout’s height as parent’s – 100, you can use the ConstraintLayout instead of the GridLayout. And you need to install the package named Xamarin.AndroidX.ConstraintLayout at first.

And then:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
    android:id="@+id/layout1"
    app:layout_constraintBottom_toBottomOf="parent"
    android:layout_width="match_parent"
    android:layout_height="100dp"/>
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="0dp" // in the ConstraintLayout the odp means use the rest area in the parent
    app:layout_constraintBottom_toTopOf="@+id/layout1"
    app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

In addition, the ConstraintLayout is the most using layout in the native android, it can design many effects which is hard for the other layouts to implement.

Answered By – Liyun Zhang – MSFT

Answer Checked By – Pedro (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published