Databinding and included layouts: Cannot find setter attribute for onClick

孤街浪徒 提交于 2019-12-22 11:34:12

问题


I'm trying to set an OnClickListener for an <include>d layout, but receive a data binding error at compile time stating that data binding "Cannot find the setter for attribute 'android:onClick' with parameter type android.view.View.OnClickListener".

Context here is that I'm using data binding to inflate the included layout, so that I can pass values into it from a viewModel that I've bound to the including layout.

I've tried various syntax for the data binding expression:

  • @{viewModel::onClickFunction}
  • @{viewModel.onClickFunction}
  • @{() -> viewModel.onClickFunction()}
  • @{(view) -> viewModel.onClickFunction()}
  • @{_ -> viewModel.onClickFunction()}

I've tried all of the above with onClickFunction as a function, and also as an OnClickListener object.

Other related questions on Stack Overflow seem to solve this issue by cleaning the project to regenerate the databinding files, but that hasn't worked for me.

Relevant code snippets below:

viewModel

class MyViewModel() {
    val onClickFunctionAsAListener: OnClickListener = object:OnClickListener{
        override fun onClick(v: View?) {
            //Do something
        }
    }

    fun onClickFunction() {
            //Do something
    }
}

Including layout

<layout>

    <data>
        <variable name="viewModel" type="full.package.name.MyViewModel"/>
    </data>

    <LinearLayout>
        <include 
            layout="@layout/included_layout"
            android:onClick="@{viewModel.onClickListener}"
            app:customAttribute="@{`someText`}/>
    </LinearLayout>

</layout>

Included layout

<layout>

    <data>
        <variable name="customAttribute" type="String"/>
    </data>

    <TextView
        layout="@layout/included_layout"
        android:text="@{customAttribute}"/>

</layout>

回答1:


It seems that you can't actually assign an OnClick handler to an <include> tag directly. I managed to get it to work by adding another variable to IncludedLayouts data binding class, and then assigning the OnClickListener to IncudedLayouts root view in XML.

After the changes, my files looked like this:

viewModel

class MyViewModel() {
    val onClickFunction: OnClickListener = object:OnClickListener{
        override fun onClick(v: View?) {
            //Do something
        }
    }
}

Including layout

<layout>

    <data>
        <variable name="viewModel" type="full.package.name.MyViewModel"/>
    </data>

    <LinearLayout>
        <include 
            layout="@layout/included_layout"
            app:onClick="@{viewModel.onClickListener}"
            app:customAttribute="@{`someText`}/>
    </LinearLayout>

</layout>

Included layout

<layout>

    <data>
        <variable name="customAttribute" type="String"/>
        <variable name="onClick" type="android.view.View.OnClickListener"/>
    </data>

    <TextView
        layout="@layout/included_layout"
        android:text="@{customAttribute}"
        android:onClick="@{onClick}"/>

</layout>



回答2:


include tag does not support onClick method directly. While the selected answer is correct, instead of passing onClickLister to include layout (or having custom @BindingAdapter, which is also another solution), I would just wrap my include inside a RecyclerView and onClick on RecyclerView.

<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="@{()-> viewModel.yourFunction()}">
    <include layout="@layout/custom_layout"/>

It's a workaround, but works as charm.



来源:https://stackoverflow.com/questions/52898833/databinding-and-included-layouts-cannot-find-setter-attribute-for-onclick

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