Coma del separador decimal (‘,’) con númeroAlta entrada decimal en EditarTexto

El inputType numberDecimal en EditText usa el punto ‘.’ como separador decimal. En Europa es común usar una coma ‘,’ en su lugar. Aunque mi configuración regional está establecida como alemana, el separador decimal sigue siendo el ‘.’

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

Una solución temporal (hasta que Google solucione este error) es usar un EditText con android:inputType="numberDecimal" y 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’ que se ofrecen aquí:

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

Teniendo en cuenta el separador de locale

Siguiente Code Currency Mask para EditText ($ 123,125.155)

Diseño Xml

   

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á creando instancias de EditText mediante progtwigción. Seguí adelante y modifiqué la clase DigitsKeyListener incluida de la API 14 para permitir la coma y el período como separador decimal.

Para usar esto, llame a setKeyListener() en EditText , por ej.

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

Sin embargo, todavía tienes que usar el truco de Martin en el TextChangedListener donde reemplazas las comas por 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 usar la siguiente solución para incluir también coma como entrada válida:

A través de XML:

  

Progtwigdo:

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

De esta forma, el sistema Android mostrará el teclado numérico y permitirá la entrada de la coma. Espero que esto responda la pregunta 🙂

Para soluciones Mono (Droid):

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

Usted 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 luego podrías usar 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; } 

}

podrías usar lo siguiente para diferentes configuraciones regionales

 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 agrega:

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

que no te olvides de reemplazar “,” con “.” entonces Float o Double pueden analizarlo sin errores.

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

  

De esta manera cuando presiona el ‘.’ en el teclado suave no pasa nada; solo se permiten números y coma.

En mi humilde opinión, el mejor enfoque para este problema es simplemente utilizar el InputFilter. Una buena idea es DecimalDigitsInputFilter . Entonces puedes 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" y android:digits="0123456789.,"

Luego, en algún lugar de su código, cuando el usuario haga clic en guardar o después de ingresar el texto (use un oyente).

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

Decidí cambiar la coma a punto solo durante la edición. Aquí está mi solución alternativa difícil y relativa:

  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 usará coma o punto depende de Locale

No sé por qué tus respuestas son tan complicadas. Si hay un error en el SDK, debes anularlo o seguirlo.

He elegido la segunda forma de resolver ese problema. Si formatea su cadena como Locale.ENGLISH y luego la pone en EditText (incluso como una cadena vacía). Ejemplo:

String.format(Locale.ENGLISH,"%.6f", yourFloatNumber);

Persiguiendo esa solución, tu resultado es compatible con el teclado mostrado. Luego flotan y los números dobles funcionan de manera típica para los lenguajes de progtwigción con punto en lugar de coma.

Mi solución es:

  • En la actividad principal:

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

  • En el archivo xml: android:imeOptions="flagNoFullscreen" android:inputType="numberDecimal"

y tomé el doble en editText como una cadena.

Puedo confirmar que las soluciones propuestas no funcionan en Samsung IME (al menos en S6 y S9) y tal vez LG. Todavía muestran un punto como separador decimal independientemente de la configuración regional. Cambiar al IME de Google corrige esto, pero no es una opción para la mayoría de los desarrolladores.

Tampoco se ha corregido en Oreo para estos teclados ya que es una solución que Samsung y / o LG tienen que hacer y luego presionar incluso a sus antiguos teléfonos.

En su lugar, he bifurcado el proyecto de teclado numérico y he añadido un modo en el que se comporta como un fork de IME. Vea la muestra del proyecto para más detalles. Esto funcionó bastante bien para mí y es similar a muchos de los IME falsos de “entrada de PIN” que ve en las aplicaciones bancarias.

Ejemplo de captura de pantalla de la aplicación