This is my BindingAdapter
:
@BindingAdapter(value = *arrayOf(\"bind:commentsAdapter\", \"bind:itemClick\", \"bind:avatarClick\", \"bind:scrolledU
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
}
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 = {}