Applying databinding adapter to include tag

落爺英雄遲暮 提交于 2019-12-10 10:37:33

问题


I'm using databinding in my project and I have one for setting a visibility condition from the viewmodel:

<View
   app:visibilityCondition="@{viewModel.showingItems}" />

This all works fine, but suddenly when I want to use it on an include tag like this:

<include
   layout="@layout/my_include_layout
   app:visibilityCondition="@{viewModel.showingItems}" />

It doesn't build, with the following error:

e: [kapt] An exception occurred: android.databinding.tool.util.LoggedErrorException: Found data binding errors. Cannot find the setter for attribute 'app:visibilityCondition' with parameter type boolean on com.example.CustomBinding.

Since the CustomBinding class doesn't actually extend from View, but instead ViewDataBinding, it doesn't look like I have a way to do this.

Is there a way around that, or am I forced to set the visibility of this included layout programatically? I know that will work, but I'd really like to keep it within the databinding if possible.


回答1:


Apparently, currently you are not able to use BindingAdapters with included layout elements, but you can pass your variables inside the included layouts (for them to handle).

What keshav Aggarwal proposed is almost ok. You will have to pass the data inside the included layout, but exposing the whole ViewModel inside the layout is unnecessary and a bit inelegant.

  1. Modify the my_include_layout, adding a variable with the bound parameter.
<layout>
    <data>
        <variable
            name="visibilityCondition"
            type="<the_type_of_the_visibility>"/>
    </data>
    <View
        app:visibilityCondition="@{visibilityCondition}"/>
</layout>
  1. Use bind namespace to pass the visibility parameter inside the included layout:
<include
   layout="@layout/my_include_layout
   bind:visibilityCondition="@{viewModel.showingItems}" />



回答2:


So, there is some catch if you want Data Binding to work when you are using include in your layouts, So do these things:

Step 1: Change your xml file in which you are using include tag to something like this. Look closely how i am playing with the variable names in this Data Binding.

<data>
     <import type="com.example.jenny.MyViewModel"/>
     <variable
         name="viewModelNew"
         type="MyViewModel"/>

      <include
         layout="@layout/my_include_layout
         app:viewModel="@{viewModelNew}"/> <!--this, viewModel is the variable declared in xml which you are including here-->
</data>

Step 2: And in the layout which you are including i.e. in my_include_layout, do the Real Data Binding there like this:

<data>
    <import type="com.example.jenny.MyViewModel"/>
    <variable
        name="viewModel"
        type="MyViewModel"/>
</data>

  <View
     app:visibilityCondition="@{viewModel.showingItems}"/><!--the real Data Binding is happening here-->

Step 3: Also, in your activity or fragment, where ever you are initializing Data Binding, do write

dataBinding.viewModelNew = new MyViewModel() // or something like this, you have to initialze the data binding variable

Let me know, if this helps.




回答3:


Assuming that your included layout still sets visibility condition based on viewModel as shown in your first code snippet and that it must then have a <data> section that defines viewModel, what I usually do is set that in the include statement. For example:

<include
    bind:viewModel="@{viewModel}"
    layout="@layout/my_include_layout"/>


来源:https://stackoverflow.com/questions/50722783/applying-databinding-adapter-to-include-tag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!