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

时间:2018-04-11 20:45:23

标签: android data-binding kotlin higher-order-functions

我在使用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

我现在一直在努力解决这个问题,而且我尝试过的都没有,所以任何帮助都会受到赞赏。

4 个答案:

答案 0 :(得分:5)

使用function: Runnable代替function: () -> Unit

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

另一方面,() -> Unit看起来像kotlin.jvm.functions.Function0,它是一个接受0输入并返回Unit.INSTANCE的函数。

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

答案 1 :(得分:0)

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

在Listener Bindings中,只有你的返回值必须与监听器的预期返回值匹配(除非它期望无效)

有关错误的更多信息:

  

无法生成视图绑定器java.lang.StackOverflowError

阅读this文章。希望它能帮到你!!

答案 2 :(得分:-1)

声明() -> Unit建议一个不接受任何输入并且不返回任何内容的函数(Unit是此语句中的返回类型)。你的功能应如下所示:

fun testFunction() = {}

答案 3 :(得分:-1)

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
}