Using DataBinding, I will write about the stumbling point and how to solve it. (Half is a memorandum) There are a lot of tips when creating a custom setter (BindingAdapter annotation).
When I made a custom setter in Java, I could write it like this.
@BindingAdapter("imageUrl")
public static void loadImage(ImageView view, String url) {
   // do something
}
First, I wrote a custom setter in Kotlin:
class ImageViewBindingAdapter {
    companion object {
        @BindingAdapter("imageUrl")
        @JvmStatic
        fun loadImage(view: ImageView, imageUrl: String) {
            // do something
        }
    }
}
DataBindingAttribute.Companion is not static and requires an object to use, retrieved from the DataBindingComponent.
The static method using companion object will result in the above error.
You can write a custom setter by the following method.
object ImageViewBindingAdapter {
    @BindingAdapter("imageUrl")
    @JvmStatic
    fun loadImage(view: ImageView, imageUrl: String) {
        // do something
    }
}
You can also use Kotlin extension functions.
object ImageViewBindingAdapter {
    @BindingAdapter("imageUrl")
    @JvmStatic
    fun ImageView.loadImage(imageUrl: String) {
        // do something
    }
}
XML is the same for both Java and Kotlin.
<ImageView 
    app:imageUrl="@{viewModel.imageUrl}" />
With Java, I could write like this.
@BindingAdapter({"imageUrl", "error"})
public static void loadImage(ImageView view, String url, Drawable error) {
   // do something
}
This is the case with Kotlin.
object ImageViewBindingAdapter {
    @BindingAdapter("imageUrl", "error")
    @JvmStatic
    fun ImageView.loadImage(imageUrl: String, error: Drawable) {
        // do something
    }
}
In XML, write:
<ImageView 
    app:imageUrl="@{viewModel.imageUrl}"
    app:error="@{@drawable/errorImage}" />
As shown below, it does not work well if only some parameters are specified.
<ImageView 
    app:imageUrl="@{viewModel.imageUrl}" />
This is because the BindingAdapter's requireAll attribute defaults to true.
In this case, it will not be called unless all parameters are specified.
To make it called by some parameters, rewrite BindingAdapter as follows.
@BindingAdapter("imageUrl", "error", requireAll = false)
I wanted to set Int to BindingAdapter, so I wrote the following, but it didn't work.
object ImageViewBindingAdapter {
    @BindingAdapter("imageUrl", "position")
    @JvmStatic
    fun ImageView.loadImage(imageUrl: String, position: Int) {
        // do something
    }
}
<ImageView 
    app:imageUrl="@{viewModel.imageUrl}"
    app:position="1" />
The cause lies in the way it is written in XML, and it works if you change it as follows.
<ImageView 
    app:imageUrl="@{viewModel.imageUrl}"
    app:position="@{1}" />
If you want to pass a Boolean, write:
<ImageView 
    app:imageUrl="@{viewModel.imageUrl}"
    app:dispflag="@{true}" />
I don't know why I have to write this, so please let me know if anyone knows.
You can import the R class as follows.
<data>
    <import type="com.sample.R"/>
    <variable 
        name="viewModel"
        type="com.sample.TestViewModel" />
</data>
<ImageView 
    app:src="@{viewModel.resourceId ?: R.drawable.error}" />
First, I checked if there was an Adapter provided as standard. https://android.googlesource.com/platform/frameworks/data-binding/+/master/extensions/baseAdapters/src/main/java/android/databinding/adapters
For example, if you want to use ʻandroid: onTextChanged of ʻEditTextView, [TextViewBindingAdapter.java](https://android.googlesource.com/platform/frameworks/data-binding/+/master/extensions/baseAdapters/src/ main / java / android / databinding / adapters / TextViewBindingAdapter.java) already has a BindingAdapter so you can use it.
There is also a description of BindingMethod here, so you may not need to bother to prepare a method BindingMethod like set ** Listener.
When I want to use a method that has Context as an argument in DataBinding, I referred to the following article.
Just pass it as context and it will work.
Handle method that passes context as argument in DataBinding
Recommended Posts