2

i'm trying to use <include> tag with data-binding to re-use one common layout.
Each re-used layout has to set different label.
To achieve this, i'm trying to pass this value as a data-binding parameter (bind:test).
The problem occurs when i try to use the variable received from parent xml (sync_fragment.xml) in included xml (sync_row.xml).
In the line of "android:text='@{test}", Android studio xml syntax underline 'test' and says: "Cannot find identifier 'test'".
The only thing different from docs i have done is not to check Android Support from Android SDK menù in Android Studio (because i don't have this entry in the list!).
How can i solve this problem?
Thanks.

Android Studio version: 3.6.1
Gradle version: 5.6.4

File: sync_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:weightSum="12">
            <include
                android:id="@+id/includedLayout1"
                layout="@layout/sync_row"
                bind:test='@{"TEST_DATA_BIND1"}' />

            <include
                android:id="@+id/includedLayout2"
                layout="@layout/sync_row"
                bind:test='@{"TEST_DATA_BIND2"}' />

            <include
                android:id="@+id/includedLayout3"
                layout="@layout/sync_row"
                bind:test='@{"TEST_DATA_BIND3"}' />
    </LinearLayout>
</layout>

File: sync_row.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="test" type="String" />
    </data>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text='@{test}'/>
    </LinearLayout>
</layout>

Gradle file:

...
dataBinding {
    enabled = true
}
...  

EDIT:
I've just updated Android Studio version to 3.6.2.
Red highlight problem seems to be disappeared.
I'm still not able to print the value on the fragment, always empty string!
I've also tried to force output inside sync_row.xml, setting directly bind:text='@{"hello"}'. No success, still empty label printed in view. Gradle version: 5.6.4

2 Answers 2

2

according to Google specifications, you cannot enter strings directly in the bind in layout.xml.

You should first put the strings in strings.xml and then bind them to layout.xml.

//strings.xml
<string name="TEST_DATA_BIND1"> TEST_DATA_BIND1 </string>
<string name="TEST_DATA_BIND2"> TEST_DATA_BIND2 </string>
<string name="TEST_DATA_BIND3"> TEST_DATA_BIND3 </string>

//sync_fragment.xml
<include
    android:id="@+id/includedLayout1"
    layout="@layout/sync_row"
    bind:test='@{@string/TEST_DATA_BIND1}' />

<include
    android:id="@+id/includedLayout2"
    layout="@layout/sync_row"
    bind:test='@{@string/TEST_DATA_BIND2}' />

<include
    android:id="@+id/includedLayout3"
    layout="@layout/sync_row"
    bind:test='@{@string/TEST_DATA_BIND3}' />

Or, put the string in the class, and then bind it to layou.xml.

// Constants.kt //*This is a test class, you should use your own class
const val TEST_DATA_BIND1 = "TEST_DATA_BIND1"
const val TEST_DATA_BIND2 = "TEST_DATA_BIND2"
const val TEST_DATA_BIND3 = "TEST_DATA_BIND3"

//sync_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto">
    <data>
        <import type="your_package_name.ConstantsKt"/>
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:weightSum="12">
            <include
                android:id="@+id/includedLayout1"
                layout="@layout/sync_row"
                bind:test='@{ConstantsKt.TEST_DATA_BIND1}' />

            <include
                android:id="@+id/includedLayout2"
                layout="@layout/sync_row"
                bind:test='@{ConstantsKt.TEST_DATA_BIND2}' />

            <include
                android:id="@+id/includedLayout3"
                layout="@layout/sync_row"
                bind:test='@{ConstantsKt.TEST_DATA_BIND3}' />
    </LinearLayout>
</layout>
Sign up to request clarification or add additional context in comments.

1 Comment

Why xmlns:bind instead of xmlns:app?
1

Put your string in string.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:weightSum="12">

            <include
                android:id="@+id/includedLayout1"
                layout="@layout/sync_row"
                bind:test='@{@string/your_string}' />

    </LinearLayout>
</layout>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.