Reputation: 6572
The above example works properly, because release 1.0-rc4 fixed the issue of needing the unnecessary variable.
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?
Upvotes: 182
Views: 113974
Reputation: 20926
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"/>
....
Upvotes: 305
Reputation: 338
Just you make sure your include layout has enabled dataBinding tag
below code is my layout that I include in other layout
<data>
<variable
name="backBinding"
type="String" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cl_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_30"
android:layout_marginTop="@dimen/dimen_30"
android:padding="@dimen/dimen_2"
app:layout_constraintStart_toStartOf="parent">
<ImageView
android:id="@+id/iv_back"
android:layout_width="@dimen/dimen_10"
android:layout_height="@dimen/dimen_20"
android:contentDescription="@string/back"
android:src="@drawable/ic_back"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_back"
style="@style/AidoFTTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_10"
android:text="@string/face_training"
android:textSize="@dimen/text_20"
app:layout_constraintBottom_toBottomOf="@id/iv_back"
app:layout_constraintStart_toEndOf="@id/iv_back"
app:layout_constraintTop_toTopOf="@id/iv_back" />
</androidx.constraintlayout.widget.ConstraintLayout>
here I am including in my main layout
<data>
<variable
name="viewModel"
type="com.ingenDynamic.coreaidokotlin.viewModels.VideoCallViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/aido_main_background"
tools:context=".ui.aidoVideoCall.ContactActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/back_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen_20"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_appBar">
<include
android:id="@+id/back"
layout="@layout/app_back_layout"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
and directly I can access my included layout
binding.backLayout.setOnClickListener { finish() }
binding.back.tvBack.text = getText(R.string.video_call)
Upvotes: 0
Reputation: 779
I would like to add, I had the similar problem. My problem was that the variable name was title, the same as id name. There was no compile error. (Not 100% sure was that a problem, I also clean the project)
<?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"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="title"
type="String" />
</data>
...
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/title"...>
<androidx.appcompat.widget.AppCompatTextView>
...
</layout>
Upvotes: 0
Reputation: 1020
it seems you have empty data tag in your xml file please cross check, it is making cause to not generate include layout file
<data>
</data>
remove this tag if your not using, will solve the problem
Upvotes: 0
Reputation: 289
just set an id for your include layout
<include
android:id="@+id/layout"
layout="@layout/buttons" />
then
BUTTONSBINDING binding = yourMainBinding.layout;
BUTTONSBINDING
is res/layout/buttons.xml
now :
binding.button.setText("simple_Way");
Upvotes: 25
Reputation: 153
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}" />
Upvotes: 6
Reputation: 59004
Just set
id
to included layout, and usebinding.includedLayout.anyView
.
This example helps passing a value to <include
& accessing included views in code.
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.
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>
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
Upvotes: 78
Reputation: 195
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)
Upvotes: 5