简体   繁体   English

使用包含标签的 Android 数据绑定

[英]Android Data Binding using include tag

Update note:更新说明:

The above example works properly , because release 1.0-rc4 fixed the issue of needing the unnecessary variable.上面的例子可以正常工作,因为 1.0-rc4 版本修复了需要不必要变量的问题。

Original question:原始问题:

I do exactly as it is described in the documentation and it does not work:我完全按照文档中的描述进行操作,但它不起作用:

main.xml:主.xml:

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

buttons.xml:按钮.xml:

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

MyActivity.java:我的活动.java:

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

how to get button?如何获得按钮?

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:按钮.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.从 1.0-rc4(刚刚发布)开始,您不再需要该变量。 You can simplify it to:您可以将其简化为:

buttons.xml:按钮.xml:

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

main.xml:主文件:

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

Easy Complete Example简单的完整示例

Just set id to included layout, and use binding.includedLayout.anyView .只需将id设置为包含布局,并使用binding.includedLayout.anyView

This example helps passing a value to <include & accessing included views in code.此示例有助于将值传递给<include并访问代码中包含的视图。

Step 1第1步

You have layout_common.xml , want to pass String to included layout.您有layout_common.xml ,想要将String传递给包含的布局。

You will create String variable in layout and refer this String to TextView .您将在布局中创建String变量并将此String引用到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第2步

Include this layout to parent layout.将此布局包含到父布局中。 Give an id to included layout, so that we can use that in binding class.为包含的布局提供一个id ,以便我们可以在绑定类中使用它。 Now you can pass String passedText to your <include tag.现在您可以将 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>
  • You can use now binding.includedLayout.textView in your class.您现在可以在类中使用binding.includedLayout.textView
  • 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注意两个布局(父和包含)都应该是binding layout ,用<layout包裹

just set an id for your include layout只需为您的包含布局设置一个 id

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

then然后

BUTTONSBINDING binding = yourMainBinding.layout;

BUTTONSBINDING is res/layout/buttons.xml BUTTONSBINDING是 res/layout/buttons.xml

now :现在 :

binding.button.setText("simple_Way");

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)

You can make your bind work on your include just adding a ID to it like so:你可以让你的绑定在你的包含上工作,只需向它添加一个 ID,如下所示:

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

it seems you have empty data tag in your xml file please cross check, it is making cause to not generate include layout file您的 xml 文件中似乎有空数据标签,请交叉检查,这是导致不生成包含布局文件的原因

 <data>

</data>

remove this tag if your not using, will solve the problem如果您不使用,请删除此标签,将解决问题

I would like to add, I had the similar problem.我想补充一下,我有类似的问题。 My problem was that the variable name was title, the same as id name.我的问题是变量名称是标题,与 id 名称相同。 There was no compile error.没有编译错误。 (Not 100% sure was that a problem, I also clean the project) (不是 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>

Just you make sure your include layout has enabled dataBinding tag只需确保您的包含布局已启用 dataBinding 标记

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.backLayout.setOnClickListener {finish()}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM