Ok, hier ist ein besserer Weg, um mit Währungsformaten umzugehen, Rückwärts-Tastendruck löschen. Der Code basiert auf dem obigen @ androidcurious-Code ... Es werden jedoch einige Probleme im Zusammenhang mit dem Löschen von Rückwärtsbewegungen und einige Analyse-Ausnahmen behandelt:
http://miguelt.blogspot.ca/2013/01/textwatcher-for-currency-masksformatting .html
[UPDATE] Die vorherige Lösung hatte einige Probleme ... Dies ist eine bessere Lösung: http://miguelt.blogspot.ca/2013/02/update-textwatcher-for-currency.html
Und ... hier sind die Einzelheiten:
Dieser Ansatz ist besser, da er die herkömmlichen Android-Mechanismen verwendet. Die Idee ist, Werte zu formatieren, nachdem der Benutzer die Ansicht existiert.
Definieren Sie einen InputFilter, um die numerischen Werte einzuschränken. Dies ist in den meisten Fällen erforderlich, da der Bildschirm nicht groß genug ist, um lange EditText-Ansichten aufzunehmen. Dies kann eine statische innere Klasse oder nur eine andere einfache Klasse sein:
/** Numeric range Filter. */
class NumericRangeFilter implements InputFilter {
/** Maximum value. */
private final double maximum;
/** Minimum value. */
private final double minimum;
/** Creates a new filter between 0.00 and 999,999.99. */
NumericRangeFilter() {
this(0.00, 999999.99);
}
/** Creates a new filter.
* @param p_min Minimum value.
* @param p_max Maximum value.
*/
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) {
// Returning null will make the EditText to accept more values.
return null;
}
} catch (NumberFormatException p_ex) {
// do nothing
}
// Value is out of range - return empty string.
return "";
}
}
Definieren Sie eine Klasse (innere statische oder nur eine Klasse), die View.OnFocusChangeListener implementiert. Beachten Sie, dass ich eine Utils-Klasse verwende. Die Implementierung finden Sie unter "Beträge, Steuern".
/** Used to format the amount views. */
class AmountOnFocusChangeListener implements View.OnFocusChangeListener {
@Override
public void onFocusChange(View p_view, boolean p_hasFocus) {
// This listener will be attached to any view containing amounts.
EditText v_amountView = (EditText)p_view;
if (p_hasFocus) {
// v_value is using a currency mask - transfor over to cents.
String v_value = v_amountView.getText().toString();
int v_cents = Utils.parseAmountToCents(v_value);
// Now, format cents to an amount (without currency mask)
v_value = Utils.formatCentsToAmount(v_cents);
v_amountView.setText(v_value);
// Select all so the user can overwrite the entire amount in one shot.
v_amountView.selectAll();
} else {
// v_value is not using a currency mask - transfor over to cents.
String v_value = v_amountView.getText().toString();
int v_cents = Utils.parseAmountToCents(v_value);
// Now, format cents to an amount (with currency mask)
v_value = Utils.formatCentsToCurrency(v_cents);
v_amountView.setText(v_value);
}
}
}
Diese Klasse entfernt das Währungsformat beim Bearbeiten - basierend auf Standardmechanismen. Beim Beenden des Benutzers wird das Währungsformat erneut angewendet.
Es ist besser, einige statische Variablen zu definieren, um die Anzahl der Instanzen zu minimieren:
static final InputFilter[] FILTERS = new InputFilter[] {new NumericRangeFilter()};
static final View.OnFocusChangeListener ON_FOCUS = new AmountOnFocusChangeListener();
Schließlich in der onCreateView (...):
EditText mAmountView = ....
mAmountView.setFilters(FILTERS);
mAmountView.setOnFocusChangeListener(ON_FOCUS);
Sie können FILTERS und ON_FOCUS für eine beliebige Anzahl von EditText-Ansichten wiederverwenden.
Hier ist die Utils-Klasse:
public class Utils {
private static final NumberFormat FORMAT_CURRENCY = NumberFormat.getCurrencyInstance();
/** Parses an amount into cents.
* @param p_value Amount formatted using the default currency.
* @return Value as cents.
*/
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 {
// p_value doesn't have a currency format.
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;
}
}
}
/** Formats cents into a valid amount using the default currency.
* @param p_value Value as cents
* @return Amount formatted using a currency.
*/
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(",", "");
}
/** Formats cents into a valid amount using the default currency.
* @param p_value Value as cents
* @return Amount formatted using a currency.
*/
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());
}
}