Home » Android » java – Android Data Binding using include tag

java – Android Data Binding using include tag

Posted by: admin March 11, 2020 Leave a comment

Questions:

Update note:

The above example works properly, because release 1.0-rc4 fixed the issue of needing the unnecessary variable.

Original question:

I do exactly as it is described in the documentation and it does not work:

main.xml:

<layout xmlns:andr...
    <data>
    </data>
       <include layout="@layout/buttons"></include>
....

buttons.xml:

<layout xmlns:andr...>
    <data>
    </data>
    <Button
        android:id="@+id/button"
        ...." />

MyActivity.java:

 ... binding = DataBindingUtil.inflate...
binding.button; ->cannot resolve symbol 'button'

how to get button?

How to&Answers:

The problem is that the included layout isn’t being thought of as a data-bound layout. To make it act as one, you need to pass a variable:

buttons.xml:

<layout xmlns:andr...>
  <data>
    <variable name="foo" type="int"/>
  </data>
  <Button
    android:id="@+id/button"
    ...." />

main.xml:

<layout xmlns:andr...
...
   <include layout="@layout/buttons"
            android:id="@+id/buttons"
            app:foo="@{1}"/>
....

Then you can access buttons indirectly through the buttons field:

MainBinding binding = MainBinding.inflate(getLayoutInflater());
binding.buttons.button

As of 1.0-rc4 (just released), you no longer need the variable. You can simplify it to:

buttons.xml:

<layout xmlns:andr...>
  <Button
    android:id="@+id/button"
    ...." />

main.xml:

<layout xmlns:andr...
...
   <include layout="@layout/buttons"
            android:id="@+id/buttons"/>
....

Answer:

Easy Complete Example

Just set id to included layout, and use binding.includedLayout.anyView.

This example helps passing a value to <include & accessing included views in code.

Step 1

You have layout_common.xml, want to pass String to included layout.

You will create String variable in layout and refer this String to TextView.

<data>
    // declare fields
    <variable
        name="passedText"
        type="String"/>
</data>

<TextView
    android:id="@+id/textView"
    ...
    android:text="@{passedText}"/> //set field to your view.

Step 2

Include this layout to parent layout. Give an id to included layout, so that we can use that in binding class. Now you can pass String passedText to your <include tag.

activity_main.xml

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

    <LinearLayout
        ..
        >

        <include
            android:id="@+id/includedLayout"
            layout="@layout/layout_common"
            app:passedText="@{@string/app_name}" // here we pass any String 
            />

    </LinearLayout>
</layout>
  • You can use now binding.includedLayout.textView in your class.
  • You can pass any variables to included layout like above.

    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    binding.includedLayout.textView.setText("text");
    

Note Both layouts (parent & included) should be binding layout, wrapped with <layout

Answer:

An other interesting thing on this is that you can pas variables to the imported layout from the binder like this:

MainBinding binding = MainBinding.inflate(getLayoutInflater());
binding.buttons.setVariable(BR.varID, variable)

Answer:

You can make your bind work on your include just adding a ID to it like so:

<include
            android:id="@+id/loading"
            layout="@layout/loading_layout"
            bind:booleanVisibility="@{viewModel.showLoading}" />