I am running into issues trying to take a function as a parameter in a binding adapter using Kotlin/Android databinding. This example code throws e: error: cannot generate view binders java.lang.StackOverflowError
when building with no other useful info in the log.
Here is my binding adapter:
@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()}"/>
and method in my ViewModel:
fun testFunction() = Unit
I have been struggling with this for a bit now and nothing I've tried works, so any help is appreciated.
To create a custom binding adapter, you need to create an extension function of the view that will use the adapter. Then, you add the @BindingAdapter annotation. You have to indicate the name of the view attribute that will execute this adapter as a parameter in the annotation.
Binding adapters are responsible for making the appropriate framework calls to set values. One example is setting a property value like calling the setText() method. Another example is setting an event listener like calling the setOnClickListener() method.
android.databinding.InverseBindingAdapter. InverseBindingAdapter is associated with a method used to retrieve the value for a View when setting values gathered from the View.
Use function: Runnable
instead of function: () -> Unit
.
Android's data-binding compiler generates java code, to which, your kotlin function's signature looks like void testFunction()
, as kotlin adapts Unit as void when calling from java.
On the other hand, () -> Unit
looks like kotlin.jvm.functions.Function0
which is a function which takes 0 inputs and returns Unit.INSTANCE.
As you can see these two function signatures don't match, and that's why the compilation fails.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With