【问题标题】:How to access Kotlin Lambda functions from databinding in Android如何在 Android 中通过数据绑定访问 Kotlin Lambda 函数
【发布时间】:2019-05-02 09:22:34
【问题描述】:

我有以下 Wrapper 类

class ApiWrapper<I, O>(
    val response: LiveData<Resource<O>>,
    val call: (I?) -> Unit
) {
    val loading = map(response) { it.status == RequestState.LOADING }
}

我有以下数据绑定表达式

<com.google.android.material.button.MaterialButton
            android:id="@+id/signInBtn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:enabled="@{!vm.login.loading}"
            android:onClick="@{()->vm.login.call(vm.auth)}"
            android:text="@string/sign_in"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"/>

ViewModel 中的login 变量包含来自存储库的包装器对象(为简洁起见,忽略详细信息)。

现在当我运行时,我得到了这个异常

[databinding] {"msg":"在 com.fishlee.etc.api.ApiWrapper\u003ccom.fishlee.auth.Auth,com.fishlee.auth 类中找不到方法调用(com.fishlee.auth.Auth) .AuthState\u003e"

为什么数据绑定在包装类中找不到方法?

我有一个解决方法,即在ViewModel 中创建一个方法并从那里调用包装器的调用方法。但我真的很想直接从数据绑定表达式中调用它,这是 ApiWrapper 类的重点,如何使用 Kotlin 进行数据绑定?任何帮助将不胜感激!

【问题讨论】:

    标签: android kotlin lambda data-binding invoke


    【解决方案1】:

    使用数据绑定库,您仍然与 Java 世界紧密相连。在那里你只能调用方法。但是您的 Kotlin lambda 在技术上是一个接口,因此只需直接调用 invoke 方法即可。它不如对对象进行调用,但比此后定义不同的方法要好。

    android:onClick="@{()->vm.login.call.invoke(vm.auth)}"
    

    【讨论】:

    • 鉴于它是一个字段,也许您需要使用 getter 语法。 (除非你用@JvmField注释它)所以,android:onClick="@{()-&gt;vm.login.getCall.invoke(vm.auth)}"
    • @XavierRubioJansana 据我所知,数据绑定也实现了属性映射。
    • 你说得对,我认为数据绑定代码生成器负责识别是否必须在生成的代码中使用字段或 getter/setter 语法。
    • FWIW,我提交了a feature request 以允许我们只使用() 语法,绕过invoke()
    猜你喜欢
    • 2023-03-05
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    • 2020-10-20
    • 2016-06-19
    • 2015-09-05
    相关资源
    最近更新 更多