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.
I am getting ****/ data binding error ****msg:Could not find event ‘textAttrChanged’ on View type ‘android.support.design.widget.TextInputEditText’ on Android 2.1. I had to add textChanged listener like below to make it to work.
@BindingAdapter(value = {“onTextChange”, “textAttrChanged”}, requireAll = false)
public static void setTextListener(TextView view,
final TextWatcher listener,
final InverseBindingListener textChange) {
if (textChange == null) {
view.addTextChangedListener(listener);
} else {
view.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (listener != null){
listener.onTextChanged(s, start, before, count);
}
else {
textChange.onChange();
}
}
@Override
public void afterTextChanged(Editable s) {}
});
}
}
Thank You
Do you still need to use Observable types with two-way data binding?
There was a bug that required this, but it has been fixed. I believe that the latest version of Android Grade Plugin 2.2 should have the fix. Of course, if you don’t have an observable, you won’t get updates from the model, but you may not care about that.
This ended up in an infinite loop on Android Studio 2.1.3