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

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

Вот мой привязывающий адаптер:

@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

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

Ответ 1

function: Runnable использования function: Runnable вместо function:() → Unit.

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

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

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

Ответ 2

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

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

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

не может генерировать привязки вида java.lang.StackOverflowError

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

Ответ 3

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

fun testFunction() = {}