简体   繁体   中英

How to use NumberFormat with 2-way data binding in android?

I'm trying to format values in editable TextInputEditText . The idea is to show thousands separator when user is entering the value.

I have some BigDecimal value, and created converters to convert it to string applying formatting:

 <com.google.android.material.textfield.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/my_hint"
                android:inputType="numberDecimal"
                android:text="@={MyConverters.amountToString(obj.value)}" 
/>

@InverseMethod("stringToAmount")
public static String amountToString(BigDecimal value){
    if (value == null) {
        return null;
    }
    return formatter.format(value);
}

public static BigDecimal stringToAmount(String value){
    if (value == null){
        return null;
    }
    try {
        Number num = formatter.parse(value);
        BigDecimal result = new BigDecimal(num.doubleValue());
        return result;
    } catch(ParseException | NumberFormatException ex) {
        return null;
    }
}

formatter - is a NumberFormat object.

But when i start typing number in app, when the value is formatted somehow (for example thousands separator is applied) the cursors goes to the beginning of the number. How to prevent such behaviour?
Probably it's possible to apply changes only when focus will be lost from the view, but i don't know how to say binding when the changes must be applied.

Finally found a solution (probably not good enough, but working).

I did it using BindingAdapters:

<com.google.android.material.textfield.TextInputEditText
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:hint="@string/my_hint"
   android:inputType="numberDecimal"
   android:text="@={obj.value}" />

@BindingAdapter("android:text")
public static void bindBigDecimalInText(EditText editText, BigDecimal oldValue, 
   BigDecimal newValue) {
    if (oldValue == null && newValue == null) {
        return;
    }

    if (oldValue != null && newValue != null && oldValue.equals(newValue)) {
        return;
    }

    editText.setText(amountToString(newValue));

    editText.setSelection(editText.getText().length());
}

@InverseBindingAdapter(attribute = "android:text")
public static BigDecimal getBigDecimalFromBinding(TextView view) {
    String string = view.getText().toString();

    return stringToAmount(string);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM