Ok, đây là một cách tốt hơn để xử lý các định dạng Tiền tệ, tổ hợp phím xóa lùi. Mã dựa trên mã @androidcurious ở trên ... Tuy nhiên, giải quyết một số vấn đề liên quan đến xóa ngược và một số ngoại lệ phân tích cú pháp:
http://miguelt.blogspot.ca/2013/01/textwatcher-for-currency-masksformatting .html
[CẬP NHẬT] Giải pháp trước đó có một số vấn đề ... Đây là giải pháp tốt hơn: http://miguelt.blogspot.ca/2013/02/update-textwatcher-for-currency.html
Và ... đây là chi tiết:
Cách tiếp cận này tốt hơn vì nó sử dụng các cơ chế Android thông thường. Ý tưởng là định dạng các giá trị sau khi người dùng tồn tại Chế độ xem.
Xác định InputFilter để hạn chế các giá trị số - điều này là bắt buộc trong hầu hết các trường hợp vì màn hình không đủ lớn để chứa các dạng xem EditText dài. Đây có thể là một lớp bên trong tĩnh hoặc chỉ một lớp đơn giản khác:
class NumericRangeFilter implements InputFilter {
private final double maximum;
private final double minimum;
NumericRangeFilter() {
this(0.00, 999999.99);
}
NumericRangeFilter(double p_min, double p_max) {
maximum = p_max;
minimum = p_min;
}
@Override
public CharSequence filter(
CharSequence p_source, int p_start,
int p_end, Spanned p_dest, int p_dstart, int p_dend
) {
try {
String v_valueStr = p_dest.toString().concat(p_source.toString());
double v_value = Double.parseDouble(v_valueStr);
if (v_value<=maximum && v_value>=minimum) {
return null;
}
} catch (NumberFormatException p_ex) {
}
return "";
}
}
Xác định một lớp (tĩnh bên trong hoặc chỉ một lớp) sẽ triển khai View.OnFocusChangeListener. Lưu ý rằng tôi đang sử dụng lớp Utils - việc triển khai có thể được tìm thấy tại "Số tiền, Thuế".
class AmountOnFocusChangeListener implements View.OnFocusChangeListener {
@Override
public void onFocusChange(View p_view, boolean p_hasFocus) {
EditText v_amountView = (EditText)p_view;
if (p_hasFocus) {
String v_value = v_amountView.getText().toString();
int v_cents = Utils.parseAmountToCents(v_value);
v_value = Utils.formatCentsToAmount(v_cents);
v_amountView.setText(v_value);
v_amountView.selectAll();
} else {
String v_value = v_amountView.getText().toString();
int v_cents = Utils.parseAmountToCents(v_value);
v_value = Utils.formatCentsToCurrency(v_cents);
v_amountView.setText(v_value);
}
}
}
Lớp này sẽ loại bỏ định dạng tiền tệ khi chỉnh sửa - dựa trên các cơ chế tiêu chuẩn. Khi người dùng thoát, định dạng tiền tệ sẽ được áp dụng lại.
Tốt hơn nên xác định một số biến tĩnh để giảm thiểu số lượng trường hợp:
static final InputFilter[] FILTERS = new InputFilter[] {new NumericRangeFilter()};
static final View.OnFocusChangeListener ON_FOCUS = new AmountOnFocusChangeListener();
Cuối cùng, trong onCreateView (...):
EditText mAmountView = ....
mAmountView.setFilters(FILTERS);
mAmountView.setOnFocusChangeListener(ON_FOCUS);
Bạn có thể sử dụng lại FILTERS và ON_FOCUS trên bất kỳ số lượng chế độ xem EditText nào.
Đây là lớp Utils:
public class Utils {
private static final NumberFormat FORMAT_CURRENCY = NumberFormat.getCurrencyInstance();
public static int parseAmountToCents(String p_value) {
try {
Number v_value = FORMAT_CURRENCY.parse(p_value);
BigDecimal v_bigDec = new BigDecimal(v_value.doubleValue());
v_bigDec = v_bigDec.setScale(2, BigDecimal.ROUND_HALF_UP);
return v_bigDec.movePointRight(2).intValue();
} catch (ParseException p_ex) {
try {
BigDecimal v_bigDec = new BigDecimal(p_value);
v_bigDec = v_bigDec.setScale(2, BigDecimal.ROUND_HALF_UP);
return v_bigDec.movePointRight(2).intValue();
} catch (NumberFormatException p_ex1) {
return -1;
}
}
}
public static String formatCentsToAmount(int p_value) {
BigDecimal v_bigDec = new BigDecimal(p_value);
v_bigDec = v_bigDec.setScale(2, BigDecimal.ROUND_HALF_UP);
v_bigDec = v_bigDec.movePointLeft(2);
String v_currency = FORMAT_CURRENCY.format(v_bigDec.doubleValue());
return v_currency.replace(FORMAT_CURRENCY.getCurrency().getSymbol(), "").replace(",", "");
}
public static String formatCentsToCurrency(int p_value) {
BigDecimal v_bigDec = new BigDecimal(p_value);
v_bigDec = v_bigDec.setScale(2, BigDecimal.ROUND_HALF_UP);
v_bigDec = v_bigDec.movePointLeft(2);
return FORMAT_CURRENCY.format(v_bigDec.doubleValue());
}
}