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

Android 作为绑定适配器的高阶函数存在问题,android,data-binding,kotlin,higher-order-functions,Android,Data Binding,Kotlin,Higher Order Functions,我在尝试使用Kotlin/Android数据绑定将函数作为绑定适配器中的参数时遇到了问题。此示例代码在日志中没有其他有用信息的情况下生成时抛出e:error:无法生成视图绑定器java.lang.StackOverflowerError 这是我的绑定适配器: @JvmStatic @BindingAdapter("onDelayedClick") fun onDelayedClick(view: View, function: () -> Unit) { // TODO: Do s

我在尝试使用Kotlin/Android数据绑定将函数作为绑定适配器中的参数时遇到了问题。此示例代码在日志中没有其他有用信息的情况下生成时抛出
e:error:无法生成视图绑定器java.lang.StackOverflowerError

这是我的绑定适配器:

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

我已经为此挣扎了一段时间,但我尝试过的方法都不管用,因此非常感谢您的帮助。

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

fun testFunction() = {}
在这一节中,我遇到了这一行:

在侦听器绑定中,只有您的返回值必须与侦听器的预期返回值匹配(除非它预期为void)

有关错误的详细信息:

无法生成视图绑定器java.lang.StackOverflower错误


阅读文章。希望它能帮助你

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

Android的数据绑定编译器生成java代码,kotlin函数的签名类似于
void testFunction()
,因为kotlin在从java调用时将单元调整为void

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


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

Put
apply plugin:kotlin kapt'
in 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}"/>

尝试查看生成的数据绑定代码。我不认为你试图实现的目标会起作用,因为你不能使用lambdas@Chisko你确定不能使用lambdas吗?那么默认onClick是如何工作的呢?你绝对可以使用lambdas和Kotlin函数参数,这只是导致问题的
单元的返回类型。我说我想呵呵,是的,我的错,你确定数据绑定编译器会抛出同样的异常(无法生成视图绑定器java.lang.StackOverflower错误)如果我更改
单元
返回到
{}
。正如您所知道的,返回单元与返回空块完全相同,您可以自己检查Kotlin字节码以确定情况是否如此。我这样写是为了让例子尽可能简单。@EricBachhuber你找到解决办法了吗?因为我看到另一篇帖子说可能是kotlin/databinding的一个bug。@Dex Sebas据我所知没有修复程序,据我所知这是databinding编译器中的一个bug。我使用的解决方法是在参数中使用不同的返回类型(即
函数:()->Boolean
而不是
函数:()->Unit
),但这很有技巧,需要更改被调用函数的返回类型,这并不总是可能的(而且设计很差,imo).在layout/kt file类中,您是这样绑定的?“@{viewModel.itemClick()}”或“@{()->viewModel.itemClick()}”///class-fun-itemClick():Boolean{Log.e(“test”,“test”)返回true}我已经尝试了这两种方法,但都不起作用。我打开了一个问题,如果我们想向该函数传递参数?如果需要传递参数,请使用SAM接口。看见
@JvmStatic
@BindingAdapter("onDelayedClick")
fun onDelayedClick(view: View, function: () -> Unit) {
    // TODO: Do something
}
<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
}