Привязка данных и включенные макеты: не удается найти атрибут сеттера для onClick - PullRequest
0 голосов
/ 19 октября 2018

Я пытаюсь установить OnClickListener для макета <include> d, но получаю ошибку привязки данных во время компиляции, утверждая, что привязка данных "Не удается найти установщик для атрибута 'android: onClick' с типом параметра android.view.View.OnClickListener ".

Контекст здесь заключается в том, что я использую привязку данных для раздувания включенного макета, чтобы я мог передавать в него значения из viewModel, который я связал свключая макет.

Я пробовал различный синтаксис для выражения привязки данных:

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

Я пробовал все вышеперечисленное с onClickFunction как функцией, а также как OnClickListener object.

Другие связанные вопросы по переполнению стека, кажется, решают эту проблему, очищая проект для регенерации файлов привязки данных, но это не сработало для меня.

Ниже приведены соответствующие фрагменты кода:

viewModel

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

    fun onClickFunction() {
            //Do something
    }
}

Включая макет

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

Включена планировкаout

<layout>

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

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

</layout>

Ответы [ 2 ]

0 голосов
/ 09 апреля 2019
Тег

include не поддерживает метод onClick напрямую.Хотя выбранный ответ является правильным, вместо передачи onClickLister в include макет (или с пользовательским @BindingAdapter, что также является другим решением), я бы просто обернул include в RecyclerView и onClickна RecyclerView.

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

Это обходной путь, но работает как шарм.

0 голосов
/ 19 октября 2018

Кажется, что вы не можете назначить обработчик OnClick непосредственно тегу <include>.Мне удалось заставить его работать, добавив еще одну переменную в класс привязки данных IncludedLayout, а затем присвоив OnClickListener корневому представлению IncudedLayout в XML.

После изменений мои файлы выглядели так:

viewModel

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

Включая макет

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

Включенный макет

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