How do I use Android Data Binding in custom views?

… … …

As you know, Data Binding Library is a great part of the library Android Jetpackto reduce boilerplate code and bind views to data in a more efficient way than was previously possible. In this article, I’m going to explain how we can use data binding in our custom views.

… … …

Beginning of work

Most of the time, we create custom views to improve performance, customization, etc., but if you use data binding in your projects, or you don’t use it in your custom views, this is not very good. Perhaps it looks something like this:

class MyCustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    init {
        attrs?.let {
            val typedArray =
                context.obtainStyledAttributes(it, R.styleable.MyCustomView)
            // some attr handling stuffs...
            typedArray.recycle()
        }
    }
}

But if you want to use a custom view with a data binding component, then there is no need to handle these attributes.

Automatic method selection

When you define an attribute like this:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyCustomView">
        <attr name="currencyCode" format="string" />
    </declare-styleable>
</resources>

the data binding library has the ability to automatically select a method, that is, for an attribute named currencyCode the library automatically tries to find the method setCurrencyCode(arg)that takes compatible types as an argument. The attribute namespace is ignored, only the attribute name and type are used when searching for a method. On the other hand, if automatic method selection does not work for your attribute name, or you want to change the setter method for your attribute, you can use binding methods.

Binding methods

Binding methods give you the ability to change the setter for an attribute of your custom view. You can place these methods above your class using the annotation @BindingMethods, or create an empty class with this annotation.

class MyCustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    private val currencyFormatter = NumberFormat.getCurrencyInstance(Locale.getDefault())
    
    //..

    fun setCurrency(currencyCode: String?) {
        if (currencyCode.isNullOrEmpty())
            return

        currencyFormatter.currency = Currency.getInstance(currencyCode)
    }

    //..
}

define a function named whatever you want, then just put it with an attribute in the binding methods.

@BindingMethods(
    value = [
        BindingMethod(
            type = MyCustomView::class,
            attribute = "currencyCode",
            method = "setCurrency"
        )
    ]
)
class BindingMethods

with this method, you can give different setter names for your attribute.

Binding adapters

If you have functions with multiple parameters in your custom view and need to use those functions with data binding, then you should use binding adapters.

@BindingAdapter(
    value = ["paddingEnd", "paddingTop", "paddingStart", "paddingBottom"],
    requireAll = false
)
fun MyCustomView.setPaddingRelative(
    paddingEnd: Int = 0,
    paddingTop: Int = 0,
    paddingStart: Int = 0,
    paddingBottom: Int = 0
) {
    this.setPaddingRelative(paddingStart, paddingTop, paddingEnd, paddingBottom)
}

You can create a binding adapter to customize the indentation, as shown in the example.

… … …

That’s it, thanks for reading! If you liked this story please click on the up arrow and share itto help others!

If you have any comments, feel free to contact me at Twitter


The translation of the material was prepared as part of the launch of the course “Android Developer. Professional”

We invite everyone to a two-day intensive course on the topic: “Full coverage. We cover Android application with unit / integration / UI tests”


Similar Posts

Leave a Reply