首页 > 解决方案 > 如何在 android 中使用 NumberFormat 和 2 路数据绑定?

问题描述

我正在尝试将值格式化为editable TextInputEditText. 这个想法是在用户输入值时显示千位分隔符。

我有一些 BigDecimal 值,并创建了转换器以将其转换为应用格式的字符串:

 <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 - 是一个 NumberFormat 对象。

但是当我开始在应用程序中输入数字时,当值以某种方式格式化(例如应用千位分隔符)时,光标会转到数字的开头。如何防止此类行为?
可能只有当焦点从视图中丢失时才可以应用更改,但我不知道在必须应用更改时如何说绑定。

标签: javaandroidbinding

解决方案


终于找到了一个解决方案(可能不够好,但工作)。

我使用 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);
}

推荐阅读