Include layout based on condition

Viewed 868

I'm trying to include layout in my xml based on condition.

         <include
            android:id="@+id/ic_amountContainer"
            layout="@{viewModel.isDts3 ? @layout/layout_amount_edittext_container_dts3 : @layout/layout_amount_edittext_container}"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="16dp"
            app:amountDefault="@{viewModel.preApprovedAmountDefault}"
            app:amountMaxLength="@{safeUnbox(viewModel.preApprovedAmountMaxLength)}"
            app:layout_constraintTop_toBottomOf="@id/tv_preApproved" />

Both layouts have the same variables that I'm passing from here.

layout_amount_edittext_container_dts3.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<data>

    <variable
        name="amountDefault"
        type="java.lang.String" />

    <variable
        name="amountMaxLength"
        type="java.lang.Integer" />

    <variable
        name="amountEditDisabled"
        type="Boolean" />

</data>

<LinearLayout
    android:id="@+id/ll_amountContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="start"
    android:layoutDirection="ltr"
    android:orientation="horizontal">


    <EditText
        android:id="@+id/et_amount"
        style="@style/AmountEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@null"
        android:enabled="@{!amountEditDisabled}"
        android:gravity="bottom"
        android:layoutDirection="locale"
        android:maxLength="@{amountMaxLength}"
        android:minWidth="60dp"
        android:text="@{amountDefault}"
        android:textSize="@dimen/text_size_48sp"
        tools:text="80,000" />

</LinearLayout>

layout_amount_edittext_container.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<data>

    <variable
        name="amountDefault"
        type="java.lang.String" />

    <variable
        name="amountMaxLength"
        type="java.lang.Integer" />

    <variable
        name="amountEditDisabled"
        type="Boolean" />

</data>

<LinearLayout
    android:id="@+id/ll_amountContainer"
    android:layout_width="match_parent"
    android:layout_height="44dp"
    android:background="@drawable/et_background_rounded"
    android:gravity="center"
    android:layoutDirection="ltr"
    android:orientation="horizontal">

    <View
        android:id="@+id/v_amount1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <EditText
        android:id="@+id/et_amount"
        style="@style/AmountEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@null"
        android:gravity="bottom"
        android:layoutDirection="locale"
        android:maxLength="@{amountMaxLength}"
        android:minWidth="60dp"
        android:enabled="@{!amountEditDisabled}"
        android:text="@{amountDefault}"
        tools:text="80,000" />

    <View
        android:id="@+id/v_amount2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />
</LinearLayout>

I'm getting this error.

Error: ****/ data binding error ****msg:included value (@{viewModel.isDts3 ? @layout/layout_amount_edittext_container_dts3 : @layout/layout_amount_edittext_container}) must start with @layout/. file:/Users/ashwani/StudioProjects/core-app-android/app/src/main/res/layout/layout_pfo_details.xml ****\ data binding error ****

Just can't figure out what I'm doing wrong. Please advice. I searched through internet but could not found same example any where.

1 Answers

The error message is telling you that the value of the layout property must begin with @layout. From that it's not possible to apply the logic you want.

There are other solutions though.

You could get away with a single included layout (as they are very similar) and bind the isDts3 value into the include, in the same manner as you have for the amount values.

eg

<include
        android:id="@+id/ic_amountContainer"
        layout="@layout/layout_amount_edittext_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="16dp"
        app:amountDefault="@{viewModel.preApprovedAmountDefault}"
        app:amountMaxLength="@{safeUnbox(viewModel.preApprovedAmountMaxLength)}"
        app:isDts3="@{viewModel.isDts3}"
        app:layout_constraintTop_toBottomOf="@id/tv_preApproved" />

And then use the value inside the layout to set the visibility on the fields that you don't want to see. Like this

android:visibility="@{isDts3 ? View.GONE : View.VISIBLE}"

or another alternative :

Have two separate include tags inside the main layout and have the visibility set there instead. I'd say this is less desirable as your increasing the size and complexity of the layout unnecessarily but its up to you.

Related