使用include标签的Android数据绑定


116

更新说明:

上面的示例正常工作,因为版本1.0-rc4 解决了需要不必要的变量的问题。

原始问题:

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

main.xml:

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

button.xml:

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

MyActivity.java:

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

如何获得按钮?

Answers:


205

问题在于所包含的布局没有被视为数据绑定布局。要使其成为一体,您需要传递一个变量:

button.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}"/>
....

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

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

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

button.xml:

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

main.xml:

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

6
现在,1.0-rc4解决了需要不必要的变量的问题。您现在可以简单地使用:<include layout="@layout/buttons" android:id="@+id/buttons"/>。您仍然需要ID,以便它将为您生成一个公共字段,以便您可以访问“按钮视图”。
乔治·芒特

1
是否还有其他人在绑定布局上的单击事件时遇到问题?
Nilzor '16


1
这里要记住的要点是获取按钮参考,binding.{id of include tag}.button而不是binding.button。花了我一段时间才能弄清楚。
Rishabh876 '18

1
@NeonWarge在developer.android.com/topic/libraries/data-binding/…中有一个完整的示例。它添加了“数据绑定不支持将include作为合并元素的直接子元素包含”
Ewan

38

简单完整的例子

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

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

第1步

您有layout_common.xml,要传递String到包含的布局。

您将String在layout中创建变量,并将其引用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


在您的答案中,您以编程方式处理了setText事件,而不是TextView如果它是一个Button,那么您将如何处理它的click事件。我知道以编程方式 binding.includedLayout.button.setOnClickListener将是替代方法,但是如果我想onClick在XML中使用attribute本身?
iCantC

您可以传递OnClickListener到包含的布局。即使您可以通过绑定传递任何内容。检查此答案,如果您需要更多帮助,请告诉我。stackoverflow.com/a/51722829/6891563
Khemraj19年

1
当我这样做时,我只会得到一个空白字段passedText。唯一的区别是,我不包括MainActivity代码,因为我只想在<include>中传递字符串资源,并像这样保留它。为什么总是空白?
Elliptica

3

另一个有趣的事情是,您可以像这样将变量从活页夹粘贴到导入的布局中:

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


2

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

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

然后

BUTTONSBINDING binding = yourMainBinding.layout;

BUTTONSBINDING 是res / layout / buttons.xml

现在:

binding.button.setText("simple_Way");
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.