Coma de separador decimal (',') con numberDecimal inputType en EditText

133

El inputType numberDecimalen EditTextutiliza el punto '.' como separador decimal En Europa es común usar una coma ',' en su lugar. Aunque mi configuración regional está establecida en alemán, el separador decimal sigue siendo el '.'

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

mseo
fuente
1
este error finalmente se ha solucionado en Android O: issuetracker.google.com/issues/36907764
Lovis
¿dicen que está arreglado pero no puedo confirmarlo? ¿puedes?
sebastian
55
Puedo confirmar que NO está reparado, al menos en mi Nexus 4 con Android 8.1 (también conocido como LineageOS 15.1). Con Configuración-> Idioma configurado en francés (Francia), un EditText con android: inputType = "numberDecimal" ofrece el separador ',' (coma) pero aún se niega a aceptar la coma. El ofrecido '.' (punto decimal) es aceptado. Han pasado más de 9 años desde que se reportó este error por primera vez. ¿Es eso algún tipo de registro? Cojo.
pete

Respuestas:

105

Una solución alternativa (hasta que Google solucione este error) es usar un EditTextcon android:inputType="numberDecimal"y android:digits="0123456789.,".

Luego agregue un TextChangedListener a EditText con el 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
}
Martín
fuente
1
@Zoombie para que la coma (,) se muestre en su teclado depende del idioma configurado en su dispositivo. Si su entrada tiene el número de tipo Decimal y su idioma es el inglés (Estados Unidos), se mostrará en los dispositivos Nexus (referencia). Es posible que los dispositivos que no sean Nexus no respeten esto
hcpl
11
Funciona, pero tenga en cuenta que deja pasar un texto como "24,22.55". ¡Es posible que deba agregar alguna validación adicional para solucionar esto!
dimsuz
8
¿Sigue siendo el camino a seguir?
Willi Mentzel
Aún mejor, use char localizedSeparator = DecimalFormatSymbols.getInstance (). GetDecimalSeparator (); localizedFloatString = localizedFloatString.replace ('.', localizedSeparator);
southerton
44
Parece que esto es solo cambiar un error por otro. Como se implementó anteriormente, esto funcionará para las configuraciones regionales que usan, en lugar de. a costa de lo contrario, que es más común en todo el mundo. El ajuste de @ southerton ayuda con eso, sin embargo, sus usuarios pueden sorprenderse cuando tocan un. y tener un, aparece en la entrada.
Nick
30

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 configuración regional.

dstibbe
fuente
Esta es la respuesta más clara a la pregunta original. Gracias
peter.bartos
Coloque esto en onCreate (), este es el camino a seguir, en mi humilde opinión.
TechNyquist el
66
Me gusta esto, pero tenga cuidado ... hay teclados que no se preocupan por la configuración regional del usuario, por lo que el usuario no tiene la tecla ,en sus teclados. Ejemplos: teclado Samsung (KitKat).
Brais Gabin
2
Esto permitirá separadores decimales duplicados. Vea la respuesta a continuación para manejarlo: stackoverflow.com/a/45384821/6138589
Esdras Lopez
19

Máscara de moneda de código siguiente 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;
        }
    });
usuario1269737
fuente
16

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í .

EricLarch
fuente
15
¿Hay alguna noticia después de cuatro años?
Antonio Sesto
Experimentando esto en Xamarin.Forms también. La cultura es {se-SV} y el teclado numérico muestra bot "," (separador decimal) y "." (separador de miles de grupos) pero al presionar "," no se ingresa nada en el campo de texto y no se
genera
Puedo confirmar que el error aún existe.
Lensflare
arreglado en la vista previa del desarrollador de Android O
R00We
6

La respuesta de Martins no funcionará si está creando instancias de EditText mediante programación. Seguí adelante y modifiqué la DigitsKeyListenerclase incluida de API 14 para permitir tanto la coma como el punto como separador decimal.

Para usar esto, llame setKeyListener()al 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 TextChangedListenerque reemplazas comas con puntos

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;
        }
    }
}
JesperB
fuente
from doc: KeyListener solo debe usarse para casos en los que una aplicación tiene su propio teclado en pantalla y también quiere procesar eventos de teclado duro para que coincidan. developer.android.com/reference/android/text/method/…
Loda
6

podría 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));
        }
    });
}
Ismail
fuente
Esta es la mejor solución para mí, pero hay problemas con algunos teléfonos, por ejemplo, Samsung, que no muestran el coma "," en el teclado. Así que cambié esto para permitir tanto el coma como el punto, pero luego lo reemplacé de acuerdo a la ubicación
Riccardo Casatta
5

Puede usar la siguiente solución alternativa para incluir también una coma como 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 la pregunta :)

MiaN KhaLiD
fuente
Con esta solución cuando toca ",", pero el texto de edición muestra "."
Mara Jiménez
2

Para soluciones Mono (Droid):

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

Podrías 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ía 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;
}

}

Pablo
fuente
puede haber un espacio entre mil y cien, este patrón rechazaría la entrada formateada
Eric Zhao
1

En mi humilde opinión, el mejor enfoque para este problema es utilizar el InputFilter. Una buena idea es aquí 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)});
Arkadiusz Cieśliński
fuente
Funcionó de maravilla, ¡gracias! (después de tantas soluciones incorrectas arriba ... :() Pero tengo una pregunta: ¿Cómo puedo lograr que la coma (",") que se muestra en la pantalla no sea punto (".") porque en Hungría usamos la coma como separador decimal .
Abigail La'Fay
1
android: digits = "0123456789", la configuración se puede agregar a EditText. Además, en lugar de devolver nulo en DecimalDigitsInputFilter, puede devolver source.replace (".", ",") De acuerdo con la respuesta stackoverflow.com/a/40020731/1510222 no hay forma de ocultar puntos en un teclado estándar
Arkadiusz Cieśliński
1

para localizar su uso de entrada:

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

y luego agregue:

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

que no olvides reemplazar "," con "." para que Float o Double puedan analizarlo sin errores.

Milos Simic Simo
fuente
1
Esta solución permite ingresar múltiples comas
Leo Droidcoder
1

Todas las otras publicaciones aquí tenían agujeros importantes, así que aquí hay una solución que:

  • Aplicar comas o puntos basados ​​en la región no le permitirá escribir el opuesto.
  • Si EditText comienza con algún valor, reemplaza el separador correcto según sea necesario.

En el XML:

<EditText
    ...
    android:inputType="numberDecimal" 
    ... />

Variable de clase:

private boolean isDecimalSeparatorComma = false;

En onCreate, busque el separador utilizado en la configuración regional actual:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    NumberFormat nf = NumberFormat.getInstance();
    if (nf instanceof DecimalFormat) {
        DecimalFormatSymbols sym = ((DecimalFormat) nf).getDecimalFormatSymbols();
        char decSeparator = sym.getDecimalSeparator();
        isDecimalSeparatorComma = Character.toString(decSeparator).equals(",");
    }
}

También en Crear, use esto para actualizarlo si está cargando un valor actual:

// Replace editText with commas or periods as needed for viewing
String editTextValue = getEditTextValue(); // load your current value
if (editTextValue.contains(".") && isDecimalSeparatorComma) {
    editTextValue = editTextValue.replaceAll("\\.",",");
} else if (editTextValue.contains(",") && !isDecimalSeparatorComma) {
    editTextValue = editTextValue.replaceAll(",",".");
}
setEditTextValue(editTextValue); // override your current value

También en Crear, Agregar los oyentes

editText.addTextChangedListener(editTextWatcher);

if (isDecimalSeparatorComma) {
    editText.setKeyListener(DigitsKeyListener.getInstance("0123456789,"));
} else {
    editText.setKeyListener(DigitsKeyListener.getInstance("0123456789."));
}

editTextWatcher

TextWatcher editTextWatcher = 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 s) {
        String editTextValue = s.toString();

        // Count up the number of commas and periods
        Pattern pattern = Pattern.compile("[,.]");
        Matcher matcher = pattern.matcher(editTextValue);
        int count = 0;
        while (matcher.find()) {
            count++;
        }

        // Don't let it put more than one comma or period
        if (count > 1) {
            s.delete(s.length()-1, s.length());
        } else {
            // If there is a comma or period at the end the value hasn't changed so don't update
            if (!editTextValue.endsWith(",") && !editTextValue.endsWith(".")) {
                doSomething()
            }
        }
    }
};

Ejemplo de doSomething (), convertir a período estándar para manipulación de datos

private void doSomething() {
    try {
        String editTextStr = editText.getText().toString();
        if (isDecimalSeparatorComma) {
            editTextStr = editTextStr.replaceAll(",",".");
        }
        float editTextFloatValue = editTextStr.isEmpty() ?
                0.0f :
                Float.valueOf(editTextStr);

        ... use editTextFloatValue
    } catch (NumberFormatException e) {
        Log.e(TAG, "Error converting String to Double");
    }
}
Elijah Fry
fuente
0

Android tiene un formateador de números incorporado.

Puede agregar esto a su EditTextpara permitir decimales y comas: android:inputType="numberDecimal"yandroid:digits="0123456789.,"

Luego, en algún lugar de su código, ya sea cuando el usuario hace 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;
}
Luis
fuente
0

Decidí cambiar la coma por punto solo durante la edición. Aquí está mi solución simple, complicada 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á una coma o un punto depende de la configuración regional

KaMyLL
fuente
0

No sé por qué tus respuestas son tan complicadas. Si hay un error en el SDK, debe anularlo o dar la vuelta.

Elegí la segunda forma de resolver ese problema. Si formatea su cadena como Locale.ENGLISHy luego la coloca en EditText(incluso como una cadena vacía). Ejemplo:

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

Persiguiendo esa solución, su resultado es compatible con el teclado que se muestra. Luego, los números flotantes y dobles funcionan de manera típica para lenguajes de programación con punto en lugar de coma.

Dominik
fuente
0

Mi solución es:

  • En actividad principal:

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

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

y tomé el doble en editText como una cadena.

Lseb
fuente
0

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

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

En cambio, bifurqué el proyecto de teclado numérico y agregué un modo donde se comporta como un IME: fork . Vea la muestra del proyecto para más detalles. Esto ha funcionado bastante bien para mí y es similar a muchos de los IME falsos de "entrada de PIN" que ves en las aplicaciones bancarias.

Captura de pantalla de la aplicación de muestra

Kevin Read
fuente
0

Han pasado más de 8 años y estoy sorprendido, este problema aún no se ha solucionado ... Luché
con este problema simple ya que la respuesta más votada por @Martin permite escribir múltiples separadores, es decir, el usuario puede escribir "12 ,,, ,,, 12,1, 21,2, "
Además, la segunda preocupación es que en algunos dispositivos la coma no se muestra en el teclado numérico (o requiere presionar varias veces un botón de puntos)

Aquí está mi solución alternativa, que resuelve los problemas mencionados y permite al usuario escribir ''. y ',', pero en EditText verá el único separador decimal que corresponde a la configuración regional actual:

editText.apply { addTextChangedListener(DoubleTextChangedListener(this)) }

Y el observador de texto:

  open class DoubleTextChangedListener(private val et: EditText) : TextWatcher {

    init {
        et.inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
        et.keyListener = DigitsKeyListener.getInstance("0123456789.,")
    }

    private val separator = DecimalFormatSymbols.getInstance().decimalSeparator

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        //empty
    }

    @CallSuper
    override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
        et.run {
            removeTextChangedListener(this@DoubleTextChangedListener)
            val formatted = toLocalizedDecimal(s.toString(), separator)
            setText(formatted)
            setSelection(formatted.length)
            addTextChangedListener(this@DoubleTextChangedListener)
        }
    }

    override fun afterTextChanged(s: Editable?) {
        // empty
    }

    /**
     * Formats input to a decimal. Leaves the only separator (or none), which matches [separator].
     * Examples:
     * 1. [s]="12.12", [separator]=',' -> result= "12,12"
     * 2. [s]="12.12", [separator]='.' -> result= "12.12"
     * 4. [s]="12,12", [separator]='.' -> result= "12.12"
     * 5. [s]="12,12,,..,,,,,34..,", [separator]=',' -> result= "12,1234"
     * 6. [s]="12.12,,..,,,,,34..,", [separator]='.' -> result= "12.1234"
     * 7. [s]="5" -> result= "5"
     */
    private fun toLocalizedDecimal(s: String, separator: Char): String {
        val cleared = s.replace(",", ".")
        val splitted = cleared.split('.').filter { it.isNotBlank() }
        return when (splitted.size) {
            0 -> s
            1 -> cleared.replace('.', separator).replaceAfter(separator, "")
            2 -> splitted.joinToString(separator.toString())
            else -> splitted[0]
                    .plus(separator)
                    .plus(splitted.subList(1, splitted.size - 1).joinToString(""))
        }
    }
}
Leo Droidcoder
fuente
0

Solución simple, hacer un control personalizado. (Esto se hace en Android Xamarin, pero debería portarse fácilmente a Java)

public class EditTextDecimalNumber:EditText
{
    readonly string _numberFormatDecimalSeparator;

    public EditTextDecimalNumber(Context context, IAttributeSet attrs) : base(context, attrs)
    {
        InputType = InputTypes.NumberFlagDecimal;
        TextChanged += EditTextDecimalNumber_TextChanged;
        _numberFormatDecimalSeparator = System.Threading.Thread.CurrentThread.CurrentUICulture.NumberFormat.NumberDecimalSeparator;

        KeyListener = DigitsKeyListener.GetInstance($"0123456789{_numberFormatDecimalSeparator}");
    }

    private void EditTextDecimalNumber_TextChanged(object sender, TextChangedEventArgs e)
    {
        int noOfOccurence = this.Text.Count(x => x.ToString() == _numberFormatDecimalSeparator);
        if (noOfOccurence >=2)
        {
            int lastIndexOf = this.Text.LastIndexOf(_numberFormatDecimalSeparator,StringComparison.CurrentCulture);
            if (lastIndexOf!=-1)
            {
                this.Text = this.Text.Substring(0, lastIndexOf);
                this.SetSelection(this.Text.Length);
            }

        }
    }
}
Nicolai
fuente
0

Podría usar inputType="phone", sin embargo, en ese caso, tendría que lidiar con múltiples ,o .estar presente, por lo que sería necesaria una validación adicional.

bulbo raquídeo
fuente
-1

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

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

De esta manera cuando presionas el '.' en el teclado blando no pasa nada; solo se permiten números y comas.

Jorge Alcolea Coronel
fuente
44
si haces esto, entonces romperás todas las configuraciones regionales que usan '.' en lugar.
Nick