【问题标题】:Android DataBinding: @BindingAdapter in Kotlin does not recognize lambdasAndroid DataBinding:Kotlin 中的 @BindingAdapter 无法识别 lambda
【发布时间】:2018-04-08 20:19:37
【问题描述】:

这是我的BindingAdapter

@BindingAdapter(value = *arrayOf("bind:commentsAdapter", "bind:itemClick", "bind:avatarClick", "bind:scrolledUp"), requireAll = false)    
fun initWithCommentsAdapter(recyclerView: RecyclerView, commentsAdapter: CommentsAdapter,
                        itemClick: (item: EntityCommentItem) -> Unit,
                        avatarClick: ((item: EntityCommentItem) -> Unit)?,
                        scrolledUp: (() -> Unit)?) {
    //Some code here
}

initWithCommentsAdapter 是顶级函数

这是我的布局(必不可少的部分):

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto">

           <data>
               <variable
                   name="viewModel"
                   type="some.example.path.CommentsViewModel"/>
               <variable
                   name="commentsAdapter"
                   type="some.example.path.CommentsAdapter"/>
           </data>

           <android.support.v7.widget.RecyclerView
                ...
                bind:avatarClick="@{(item) -> viewModel.avatarClick(item)}"
                bind:itemClick="@{viewModel::commentClick}"
                bind:commentsAdapter="@{commentsAdapter}"
                bind:isVisible="@{viewModel.commentsVisibility}"
                bind:scrolledUp="@{() -> viewModel.scrolledUp()}"
            />
</layout>

当我在布局中为 lambda 分配 kotlin 方法调用时,在构建过程中出现这样的错误:

e: java.lang.IllegalStateException: failed to analyze: 
java.lang.RuntimeException: Found data binding errors.
****/ data binding error ****msg:cannot find method avatarClick(java.lang.Object) 
in class some.example.path.CommentsViewModel
****\ data binding error ****

或者如果我通过引用分配方法:

e: java.lang.IllegalStateException: failed to analyze: 
java.lang.RuntimeException: Found data binding errors.
****/ data binding error ****msg:Listener class kotlin.jvm.functions.Function1 
with method invoke did not match signature of any method viewModel::commentClick
file:C:\Android\Projects\...\fragment_comments.xml
loc:70:12 - 83:17
****\ data binding error ****

但我有这样的方法,类型正确,而不是 Object

问题

如何在布局中为 Kotlin 中的自定义 @BindingAdapter 分配 Kotlin lambda?

编辑

viewModel的相关部分:

class CommentsViewModel(model: CommentsModel): BaseObservable() {
    //Some binded variables here
    ...
    fun commentClick(item: EntityCommentItem) {
        //Some code here
    }

    fun avatarClick(item: EntityCommentItem) {
        //Some code here
    }
    fun scrolledUp() {
        //Some code here
    }
    ...
}

变量绑定工作得很好

【问题讨论】:

  • 能把CommentsViewModel的相关部分加进去吗?
  • 我从 viewModel 类中添加了一些相关代码
  • 与 BindingAdapter 中的类型相同
  • 你找到解决办法了吗?
  • 很遗憾没有。我使用了解决方法。我只是通过一些方法传递一个对象。但那是很久以前的事了。我已经忘记了。

标签: android kotlin android-databinding


【解决方案1】:

简答

不要使用 Kotlin 通用 lambda 类型,而是将 接口 与单个方法一起使用,该方法同时匹配方法引用 (itemClick) 或侦听器 (avatarClick) 的返回类型和参数。 您还可以使用具有单个抽象方法的抽象类,也可以使用匹配的参数和返回类型。

说明

实际上Databinding docs 从未提及 Kotlin lambda 类型用作数据绑定侦听器或方法引用,可能是因为这些 lambda 类型在后台转换为 Kotlin 的 Function1Function2... 是泛型,因此它们的一些类型信息不会进入可执行文件,因此在运行时不可用。

为什么您的scrolledUp 绑定确实有效?因为类型() -&gt; Unit 不需要泛型。它甚至可以使用 Runnable

代码

interface ItemClickInterface {
    // method may have any name
    fun doIt(item: EntityCommentItem)
}

@BindingAdapter(
    value = ["commentsAdapter", "scrolledUp", "itemClick", "avatarClick"],
    requireAll = false
)
fun initWithCommentsAdapter(
    view: View,
    commentsAdapter: CommentsAdapter,
    scrolledUp: () -> Unit,            // could have been Runnable!
    itemClick: ItemClickInterface,
    avatarClick: ItemClickInterface
) {
    // Some code here
}

【讨论】:

  • 有没有相关的官方文档?如果有,能给我一个链接吗?
【解决方案2】:

我遇到了同样的情况,并且有效的是将它声明为定义其类型的变量,这与编译器一起工作

val avatarClick:(item: EntityCommentItem)-&gt;Unit = {}

【讨论】:

  • 这是答案,但缺少更多信息
  • 已经有一段时间了,但我相信该参数最终被声明为处理程序.. avatarClick:(item: EntityCommentItem)->Unit = {}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-06
  • 1970-01-01
  • 2017-07-31
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 2014-04-07
相关资源
最近更新 更多