Decimal separator comma (',') con numberDecimal inputType en EditText

El inputType numberDecimal en EditText utiliza el punto '.' Como separador decimal. En Europa es común usar una coma ',' en su lugar. A pesar de que mi configuración regional se establece como alemán, el separador decimal sigue siendo el '.'

¿Hay una manera de obtener la coma como separador decimal?

Una solución (hasta que Google corrija este error) es usar un EditText con android:inputType="numberDecimal" and android:digits="0123456789.," .

A continuación, agregue un TextChangedListener al EditText con lo siguiente afterTextChanged:

 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 } 

Una variación de las soluciones de 'dígitos' ofrecidas aquí:

 char separator = DecimalFormatSymbols.getInstance().getDecimalSeparator(); input.setKeyListener(DigitsKeyListener.getInstance("0123456789" + separator)); 

Teniendo en cuenta el separador de localización.

Siguiendo la máscara de moneda de código para EditText ($ 123,125.155)

Diseño Xml

  <EditText android:inputType="numberDecimal" android:layout_height="wrap_content" android:layout_width="200dp" android:digits="0123456789.,$" /> 

Código

 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; } }); 

Este es un error conocido en el SDK de Android. La única solución es crear su propio teclado virtual. Puede encontrar un ejemplo de implementación aquí .

La respuesta de Martins no funcionará si está instanciando el EditText mediante programación. Seguí adelante y modificó la clase DigitsKeyListener incluida de la API 14 para permitir tanto la coma como el punto como separador decimal.

Para usar esto, llame a setKeyListener() en el EditText , por ejemplo

 // Don't allow for signed input (minus), but allow for decimal points editText.setKeyListener( new MyDigitsKeyListener( false, true ) ); 

Sin embargo, todavía tiene que utilizar el truco de Martin en TextChangedListener donde reemplazar comas con períodos

 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; } } } 

Puede utilizar la solución siguiente para incluir también coma como una entrada válida: –

A través de XML:

 <EditText android:inputType="number" android:digits="0123456789.," /> 

Programáticamente:

 EditText input = new EditText(THE_CONTEXT); input.setKeyListener(DigitsKeyListener.getInstance("0123456789.,")); 

De esta manera el sistema Android mostrará el teclado de los números y permitirá la entrada de coma. Espero que esto responda a la pregunta 🙂

Para soluciones Mono (Droid):

 decimal decimalValue = decimal.Parse(input.Text.Replace(",", ".") , CultureInfo.InvariantCulture); 

Podría hacer lo siguiente:

 DecimalFormatSymbols d = DecimalFormatSymbols.getInstance(Locale.getDefault()); input.setFilters(new InputFilter[] { new DecimalDigitsInputFilter(5, 2) }); input.setKeyListener(DigitsKeyListener.getInstance("0123456789" + d.getDecimalSeparator())); 

Y entonces usted podría utilizar un filtro de entrada:

  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; } 

}

Creo que esta solución es menos compleja que las otras escritas aquí:

 <EditText android:inputType="numberDecimal" android:digits="0123456789," /> 

De esta manera cuando presione el botón '.' En el teclado suave nada sucede; Sólo se permiten números y coma.

IMHO el mejor enfoque para este problema es simplemente utilizar el InputFilter. Una buena idea es aquí DecimalDigitsInputFilter . Entonces usted puede simplemente:

 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 tiene un formateador de números incorporado.

Puede agregar esto a su EditText para permitir decimales y comas: android:inputType="numberDecimal" and android:digits="0123456789.,"

A continuación, en algún lugar de su código, ya sea cuando el usuario hace clic en guardar o después de introducir texto (utilice un listener).

 // 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; } 

Puede utilizar lo siguiente para diferentes locales

 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)); } }); } 

Para localizar su uso de entrada:

 char sep = DecimalFormatSymbols.getInstance().getDecimalSeparator(); 

Y luego agregar:

 textEdit.setKeyListener(DigitsKeyListener.getInstance("0123456789" + sep)); 

Que no olvide reemplazar "," con "." Por lo que Float o Double pueden analizarlo sin errores.

  • Aparición automática de teclado en el inicio Actividad
  • Deshabilitar texto predictivo en EditText
  • Editado
  • Coloque el cursor al final del texto en EditText
  • Androide modificar el texto EditarTexto
  • ¿Cómo se puede cambiar el fondo y el color de la fuente de un Android EditText en Android durante la edición?
  • Barra de herramientas se mueve fuera de la pantalla cuando uso adjustpan
  • Cómo poner editable editable dentro de un listview?
  • Cómo implementar Multiline EditText con el botón ActionDone (sin el botón Enter)
  • Quitar icono de la contraseña de la muestra en Android N
  • TextInputLayout y AutoCompleteTextView
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.