161

更新说明:

上面的例子可以正常工作,因为 1.0-rc4 版本修复了需要不必要变量的问题。

原始问题:

我完全按照文档中的描述进行操作,但它不起作用:

主.xml:

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

按钮.xml:

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

我的活动.java:

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

如何获得按钮?

4

8 回答 8

272

问题是包含的布局没有被认为是数据绑定布局。要使其充当一个,您需要传递一个变量:

按钮.xml:

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

主.xml:

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

然后您可以通过按钮字段间接访问按钮:

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

从 1.0-rc4(刚刚发布)开始,您不再需要该变量。您可以将其简化为:

按钮.xml:

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

主.xml:

<layout xmlns:andr...
...
   <include layout="@layout/buttons"
            android:id="@+id/buttons"/>
....
于 2015-10-05T21:59:20.680 回答
62

简单的完整示例

只需设置id为包含布局,然后使用binding.includedLayout.anyView.

此示例有助于将值传递给<include和访问代码中包含的视图。

第1步

你有layout_common.xml,想要传递String给包含的布局。

您将在布局中创建变量并将其String参考。StringTextView

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

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

第2步

将此布局包含到父布局中。给id包含的布局,以便我们可以在绑定类中使用它。现在您可以将 String 传递passedText给您的<include标签。

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在课堂上使用。
  • 您可以像上面一样将任何变量传递给包含的布局。

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

注意两种布局(父级和包括)都应该用binding layout, 包裹<layout

于 2018-08-01T16:56:29.393 回答
19

只需为您的包含布局设置一个 id

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

然后

BUTTONSBINDING binding = yourMainBinding.layout;

BUTTONSBINDING是 res/layout/buttons.xml

现在 :

binding.button.setText("simple_Way");
于 2020-03-23T23:17:56.070 回答
3

另一个有趣的事情是,您可以将变量从活页夹中传递给导入的布局,如下所示:

MainBinding binding = MainBinding.inflate(getLayoutInflater());
binding.buttons.setVariable(BR.varID, variable)
于 2017-07-22T20:51:58.160 回答
3

您可以使您的绑定工作在您的包含上,只需向其中添加一个 ID,如下所示:

<include
            android:id="@+id/loading"
            layout="@layout/loading_layout"
            bind:booleanVisibility="@{viewModel.showLoading}" />
于 2019-08-06T16:20:41.363 回答
0

您的 xml 文件中似乎有空的数据标签,请交叉检查,这是导致不生成包含布局文件的原因

 <data>

</data>

如果您不使用,请删除此标签,将解决问题

于 2021-02-17T13:56:57.780 回答
0

我想补充一下,我有类似的问题。我的问题是变量名称是标题,与 id 名称相同。没有编译错误。(不是 100% 确定这是个问题,我也清理了项目)

<?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>
于 2021-05-12T15:38:47.373 回答
0

只需确保您的包含布局已启用 dataBinding 标记

下面的代码是我在其他布局中包含的布局

<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>

在这里我包括在我的主要布局中

<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>

我可以直接访问我包含的布局

binding.backLayout.setOnClickListener {finish()}

binding.back.tvBack.text = getText(R.string.video_call)

于 2022-01-17T13:05:27.587 回答