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?
- No puedo escribir en el EditText, desaparece cuando intento escribir algo, es porque el getView () se llama cuando modifico los datos
- OnCreateContextMenu () para EditText no funciona en dispositivos reales
- Cambiar color de sugerencia de EditText cuando se utiliza TextInputLayout
- Cambiar el color del cursor editext en API 12
- ¿Cómo se muestra el teclado numérico en un EditText en android?
- Cómo iniciar la barra de acción contextual para ver el texto de forma programática con opions por defecto copiar y seleccionar todo?
- EditTextPreference ¿Deshabilitar botones?
- ¿Cambiar el texto de la pista en AppCompatEditText en tiempo de ejecución?
- EditText cursor en la posición superior izquierda.
- Edittext - cómo ocultar underbar
- Android: se centra en EditText después de la selección de Spinner
- El teclado flexible de Android no se mostrará en 2.2 / 2.3, pero sí en 3.0+
- ¿Cómo deshabilitar el teclado popup cuando en edittext?
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.
- Cómo solicitar permisos de un servicio en Android Marshmallow
- Android Prevención Haga doble clic en un botón