Проблема с функцией более высокого порядка в качестве адаптера привязки

Я сталкиваюсь с проблемами, пытаясь получить функцию в качестве параметра в адаптере привязки, используя привязку данных Kotlin/Android. Этот пример кода бросает e: error: cannot generate view binders java.lang.StackruError при сборке без другой полезной информации в журнале.

Вот мой обязательный адаптер:

@JvmStatic
@BindingAdapter("onDelayedClick")
fun onDelayedClick(view: View, function: () -> Unit) {
    // TODO: Do something
}

XML:

        <View
            android:id="@+id/test_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:onDelayedClick="@{() -> viewModel.testFunction()}"/>

и метод в моей ViewModel:

fun testFunction() = Unit

Я немного боролся с этим сейчас, и ничто из того, что я пробовал, не работает, поэтому любая помощь приветствуется.

3 ответа

Решение

Использование function: Runnable вместо function: () -> Unit,

Компилятор привязки данных Android генерирует Java-код, для которого выглядит подпись вашей функции kotlin void testFunction(), поскольку kotlin адаптирует Unit как void при вызове из Java.

С другой стороны, () -> Unit похоже kotlin.jvm.functions.Function0 которая является функцией, которая принимает 0 входных данных и возвращает Unit.INSTANCE.

Как вы можете видеть, эти две сигнатуры функций не совпадают, и поэтому компиляция не удалась.

Положил apply plugin: 'kotlin-kapt' в build.gradle

Затем вы можете создать Binding Adapter как

@JvmStatic
@BindingAdapter("onDelayedClick")
fun onDelayedClick(view: View, function: () -> Unit) {
    // TODO: Do something
}

И XML как

<View
   android:id="@+id/test_view"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   app:onDelayedClick="@{viewModel.testFunction}"/>

И ВМ Лайк

val testFunction =  {
    // TODO: Do something
}

В разделе Обработка событий я наткнулся на эту строку:

В привязках прослушивателя только ваше возвращаемое значение должно соответствовать ожидаемому возвращаемому значению слушателя (если только оно не ожидает void)

Подробнее об ошибке:

не может сгенерировать связыватели вида java.lang.StackruError

прочитайте эту статью надеюсь, это поможет вам!!

Декларация () -> Unit предлагает функцию, которая не требует ввода и ничего не возвращает (Unit является типом возврата в этом утверждении). Ваша функция должна выглядеть так:

fun testFunction() = {}
Другие вопросы по тегам