高阶函数作为绑定适配器的问题

Issue with higher order function as a binding adapter

我 运行 遇到了尝试使用 Kotlin/Android 数据绑定将函数作为绑定适配器中的参数的问题。此示例代码在日志中没有其他有用信息的情况下构建时抛出 e: error: cannot generate view binders java.lang.WhosebugError

这是我的绑定适配器:

@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

我已经为此苦苦挣扎了一段时间,但我尝试过的都没有效果,所以非常感谢您的帮助。

声明 () -> Unit 建议一个不接受输入且 return 什么也没有的函数(Unit 是此语句中的 return 类型)。您的函数应如下所示:

fun testFunction() = {}

Event Handling 部分,我看到了这一行:

在侦听器绑定中,只有您的 return 值必须与侦听器的预期 return 值匹配(除非它期望无效)

有关错误的更多信息:

cannot generate view binders java.lang.WhosebugError

阅读 this 文章。希望对你有帮助!!

使用 function: Runnable 而不是 function: () -> Unit

Android 的数据绑定编译器生成 java 代码,您的 kotlin 函数的签名看起来像 void testFunction(),因为 kotlin 在从 [= 调用时将 Unit 适配为 void 25=]。

另一方面,() -> Unit 看起来像 kotlin.jvm.functions.Function0,它是一个接受 0 个输入和 returns Unit.INSTANCE.

的函数

如您所见,这两个函数签名不匹配,这就是编译失败的原因。

apply plugin: 'kotlin-kapt'放入build.gradle

然后你可以像

一样创建绑定适配器
@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}"/>

VM 喜欢

val testFunction =  {
    // TODO: Do something
}