Two-Way Data Binding Conversions

I’ve seen a few questions regarding using Android Data Binding with EditText, but with a different type. For example, you may want the EditText to bind to an integer value:

<EditText android:text="@={user.age}" ../>

or float value:

<EditText android:text="@={user.favoriteRationalNumber}" ../>

or maybe even a custom object.

With Android Studio 2.2’s gradle plugin, you can use a simplified conversion form:

<EditText android:text="@={`` + user.age}" ../>

This converts to and from a String from any primitive type.

However, this doesn’t work on Android Studio 2.1, nor does it work for any custom type, so you must implement it yourself. Here’s how you can do it for a float value:

@BindingAdapter("android:text")
public static void setText(TextView view, float value) {
    boolean setValue = view.getText().length() == 0;
    try {
        if (!setValue) {
            setValue = Float.parseFloat(view.getText().toString()) != value;
        }
    } catch (NumberFormatException e) {
    }
    if (setValue) {
        view.setText(String.valueOf(value));
    }
}

@InverseBindingAdapter(attribute = "android:text")
public static float getText(TextView view) {
    try {
        return Float.parseFloat(view.getText().toString());
    } catch (NumberFormatException e) {
        return 0;
    }
}

In this, you’ll haveĀ erroneous float format for text return 0. You may want to keep track of the old value and return it if there is an error. If you do, remember to use a weak reference, such as a WeakHashMap so that you don’t end up leaking View references everywhere.

Advertisements