Android DataBinding: @BindingAdapter in Kotlin does not recognize lambdas

前端 未结 2 812
小蘑菇
小蘑菇 2020-12-10 12:07

This is my BindingAdapter:

@BindingAdapter(value = *arrayOf(\"bind:commentsAdapter\", \"bind:itemClick\", \"bind:avatarClick\", \"bind:scrolledU         


        
相关标签:
2条回答
  • 2020-12-10 12:21

    Short Answer

    Instead of using Kotlin generic lambda types, use interfaces with a single method that matches both return type and parameters of your method reference (itemClick) or your listener (avatarClick). You can also use abstract classes with a single abstract method, also with matching parameters and return type.

    Explanation

    Actually the Databinding docs never mention that the Kotlin lambda types work as Databinding listeners or method references, probably because under the hood these lambda types translate to Kotlin's Function1, Function2... which are generics, and thus some of their type information doesn't make it to the executable and therefore is not available at runtime.

    Why your scrolledUp binding did work though? Because type () -> Unit has no need for generics. It could have worked even with Runnable.

    Code

    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
    }
    
    0 讨论(0)
  • 2020-12-10 12:27

    I ran into the same case, and what worked was having it declared as variable defining its type, that worked with the compiler

    val avatarClick:(item: EntityCommentItem)->Unit = {}

    0 讨论(0)
提交回复
热议问题