小数分隔符逗号(',')在EditText中使用numberDecimal inputType
EditText
的inputType
EditText
使用点“。” 作为小数分隔符。 在欧洲,通常使用逗号“,”代替。 即使我的区域设置为德语,小数点分隔符仍然是'。'
有没有办法让逗号作为小数点分隔符?
一个解决方法(直到谷歌修复这个bug)是使用android:inputType="numberDecimal"
和android:digits="0123456789.,"
的EditText
。
然后使用以下afterTextChanged将TextChangedListener添加到EditText:
public void afterTextChanged(Editable s) { double doubleValue = 0; if (s != null) { try { doubleValue = Double.parseDouble(s.toString().replace(',', '.')); } catch (NumberFormatException e) { //Error } } //Do something with doubleValue }
这里提供的“数字”解决scheme的变体:
char separator = DecimalFormatSymbols.getInstance().getDecimalSeparator(); input.setKeyListener(DigitsKeyListener.getInstance("0123456789" + separator));
考虑到区域设置分隔符。
以下代码EditText的货币掩码($ 123,125.155)
Xml布局
<EditText android:inputType="numberDecimal" android:layout_height="wrap_content" android:layout_width="200dp" android:digits="0123456789.,$" />
码
EditText testFilter=... testFilter.addTextChangedListener( new TextWatcher() { boolean isEdiging; @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { if(isEdiging) return; isEdiging = true; String str = s.toString().replaceAll( "[^\\d]", "" ); double s1 = Double.parseDouble(str); NumberFormat nf2 = NumberFormat.getInstance(Locale.ENGLISH); ((DecimalFormat)nf2).applyPattern("$ ###,###.###"); s.replace(0, s.length(), nf2.format(s1)); isEdiging = false; } });
这是Android SDK中的一个已知错误 。 唯一的解决方法是创build自己的软键盘。 你可以在这里find一个实现的例子。
如果您以编程方式实例化EditText,Martins答案将不起作用。 我继续从API 14修改包含的DigitsKeyListener
类,以逗号和句点作为小数点分隔符。
要使用它,请在EditText
上调用setKeyListener()
,例如
// Don't allow for signed input (minus), but allow for decimal points editText.setKeyListener( new MyDigitsKeyListener( false, true ) );
但是,您仍然必须在TextChangedListener
中使用Martin的技巧,用逗号replace逗号
import android.text.InputType; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.method.NumberKeyListener; import android.view.KeyEvent; class MyDigitsKeyListener extends NumberKeyListener { /** * The characters that are used. * * @see KeyEvent#getMatch * @see #getAcceptedChars */ private static final char[][] CHARACTERS = new char[][] { new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }, new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-' }, new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', ',' }, new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.', ',' }, }; private char[] mAccepted; private boolean mSign; private boolean mDecimal; private static final int SIGN = 1; private static final int DECIMAL = 2; private static MyDigitsKeyListener[] sInstance = new MyDigitsKeyListener[4]; @Override protected char[] getAcceptedChars() { return mAccepted; } /** * Allocates a DigitsKeyListener that accepts the digits 0 through 9. */ public MyDigitsKeyListener() { this(false, false); } /** * Allocates a DigitsKeyListener that accepts the digits 0 through 9, * plus the minus sign (only at the beginning) and/or decimal point * (only one per field) if specified. */ public MyDigitsKeyListener(boolean sign, boolean decimal) { mSign = sign; mDecimal = decimal; int kind = (sign ? SIGN : 0) | (decimal ? DECIMAL : 0); mAccepted = CHARACTERS[kind]; } /** * Returns a DigitsKeyListener that accepts the digits 0 through 9. */ public static MyDigitsKeyListener getInstance() { return getInstance(false, false); } /** * Returns a DigitsKeyListener that accepts the digits 0 through 9, * plus the minus sign (only at the beginning) and/or decimal point * (only one per field) if specified. */ public static MyDigitsKeyListener getInstance(boolean sign, boolean decimal) { int kind = (sign ? SIGN : 0) | (decimal ? DECIMAL : 0); if (sInstance[kind] != null) return sInstance[kind]; sInstance[kind] = new MyDigitsKeyListener(sign, decimal); return sInstance[kind]; } /** * Returns a DigitsKeyListener that accepts only the characters * that appear in the specified String. Note that not all characters * may be available on every keyboard. */ public static MyDigitsKeyListener getInstance(String accepted) { // TODO: do we need a cache of these to avoid allocating? MyDigitsKeyListener dim = new MyDigitsKeyListener(); dim.mAccepted = new char[accepted.length()]; accepted.getChars(0, accepted.length(), dim.mAccepted, 0); return dim; } public int getInputType() { int contentType = InputType.TYPE_CLASS_NUMBER; if (mSign) { contentType |= InputType.TYPE_NUMBER_FLAG_SIGNED; } if (mDecimal) { contentType |= InputType.TYPE_NUMBER_FLAG_DECIMAL; } return contentType; } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { CharSequence out = super.filter(source, start, end, dest, dstart, dend); if (mSign == false && mDecimal == false) { return out; } if (out != null) { source = out; start = 0; end = out.length(); } int sign = -1; int decimal = -1; int dlen = dest.length(); /* * Find out if the existing text has '-' or '.' characters. */ for (int i = 0; i < dstart; i++) { char c = dest.charAt(i); if (c == '-') { sign = i; } else if (c == '.' || c == ',') { decimal = i; } } for (int i = dend; i < dlen; i++) { char c = dest.charAt(i); if (c == '-') { return ""; // Nothing can be inserted in front of a '-'. } else if (c == '.' || c == ',') { decimal = i; } } /* * If it does, we must strip them out from the source. * In addition, '-' must be the very first character, * and nothing can be inserted before an existing '-'. * Go in reverse order so the offsets are stable. */ SpannableStringBuilder stripped = null; for (int i = end - 1; i >= start; i--) { char c = source.charAt(i); boolean strip = false; if (c == '-') { if (i != start || dstart != 0) { strip = true; } else if (sign >= 0) { strip = true; } else { sign = i; } } else if (c == '.' || c == ',') { if (decimal >= 0) { strip = true; } else { decimal = i; } } if (strip) { if (end == start + 1) { return ""; // Only one character, and it was stripped. } if (stripped == null) { stripped = new SpannableStringBuilder(source, start, end); } stripped.delete(i - start, i + 1 - start); } } if (stripped != null) { return stripped; } else if (out != null) { return out; } else { return null; } } }
您可以使用以下解决方法还包括逗号作为有效的input: –
通过XML:
<EditText android:inputType="number" android:digits="0123456789.," />
编程方式:
EditText input = new EditText(THE_CONTEXT); input.setKeyListener(DigitsKeyListener.getInstance("0123456789.,"));
这样Android系统会显示数字的键盘并允许input逗号。 希望这回答了这个问题:)
对于Mono(Droid)解决scheme:
decimal decimalValue = decimal.Parse(input.Text.Replace(",", ".") , CultureInfo.InvariantCulture);
你可以做到以下几点:
DecimalFormatSymbols d = DecimalFormatSymbols.getInstance(Locale.getDefault()); input.setFilters(new InputFilter[] { new DecimalDigitsInputFilter(5, 2) }); input.setKeyListener(DigitsKeyListener.getInstance("0123456789" + d.getDecimalSeparator()));
然后你可以使用一个inputfilter:
public class DecimalDigitsInputFilter implements InputFilter { Pattern mPattern; public DecimalDigitsInputFilter(int digitsBeforeZero, int digitsAfterZero) { DecimalFormatSymbols d = new DecimalFormatSymbols(Locale.getDefault()); String s = "\\" + d.getDecimalSeparator(); mPattern = Pattern.compile("[0-9]{0," + (digitsBeforeZero - 1) + "}+((" + s + "[0-9]{0," + (digitsAfterZero - 1) + "})?)||(" + s + ")?"); } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { Matcher matcher = mPattern.matcher(dest); if (!matcher.matches()) return ""; return null; }
}
我认为这个解决scheme比这里写的其他解决scheme要复杂得多:
<EditText android:inputType="numberDecimal" android:digits="0123456789," />
这样当你按'。'时 在软键盘上没有任何反应; 只有数字和逗号是允许的。
恕我直言,这个问题的最好办法是只使用InputFilter。 DecimalDigitsInputFilter是一个很好的要点。 那么你可以只是:
editText.setInputType(TYPE_NUMBER_FLAG_DECIMAL | TYPE_NUMBER_FLAG_SIGNED | TYPE_CLASS_NUMBER) editText.setKeyListener(DigitsKeyListener.getInstance("0123456789,.-")) editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,2)});
Android有一个内置的数字格式化程序。
您可以添加到您的EditText
允许小数和逗号: android:inputType="numberDecimal"
和android:digits="0123456789.,"
然后在你的代码的某处,当用户点击保存或input文本后(使用一个监听器)。
// Format the number to the appropriate double try { Number formatted = NumberFormat.getInstance().parse(editText.getText().toString()); cost = formatted.doubleValue(); } catch (ParseException e) { System.out.println("Error parsing cost string " + editText.getText().toString()); cost = 0.0; }
你可以使用下面的不同的语言环境
private void localeDecimalInput(final EditText editText){ DecimalFormat decFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault()); DecimalFormatSymbols symbols=decFormat.getDecimalFormatSymbols(); final String defaultSeperator=Character.toString(symbols.getDecimalSeparator()); editText.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) { } @Override public void afterTextChanged(Editable editable) { if(editable.toString().contains(defaultSeperator)) editText.setKeyListener(DigitsKeyListener.getInstance("0123456789")); else editText.setKeyListener(DigitsKeyListener.getInstance("0123456789" + defaultSeperator)); } }); }
让本地化您的input使用:
char sep = DecimalFormatSymbols.getInstance().getDecimalSeparator();
然后添加:
textEdit.setKeyListener(DigitsKeyListener.getInstance("0123456789" + sep));
比别忘记用“”replace“,”。 所以Float或Double可以毫无差错地parsing它。
我决定只在编辑时将逗号改成点。 这是我的棘手和相对简单的解决方法:
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { EditText editText = (EditText) v; String text = editText.getText().toString(); if (hasFocus) { editText.setText(text.replace(",", ".")); } else { if (!text.isEmpty()) { Double doubleValue = Double.valueOf(text.replace(",", ".")); editText.setText(someDecimalFormatter.format(doubleValue)); } } } });
someDecimalFormatter将使用逗号或点取决于语言环境