Десятковий комір роздільника (',') з числомDecimal inputType в EditText


133

inputType numberDecimalВ EditTextвикористовує точку «» як десятковий роздільник. У Європі зазвичай застосовується кома «,». Навіть незважаючи на те, що мою локаль встановлено як німецьку, десятковою роздільником є ​​все ще '.'

Чи є спосіб отримати кому як десятковий роздільник?



1
Цю проблему було нарешті виправлена в Android O: issuetracker.google.com/issues/36907764
Ловіс

вони кажуть, що це виправлено, але я не можу підтвердити це фіксованим? ти можеш?
себастьян

5
Я можу підтвердити, що це НЕ зафіксовано, принаймні на моєму Nexus 4, на якому працює Android 8.1 (він же LineageOS 15.1). Якщо параметри-> Мова встановлено на французьку (Франція), EditText з android: inputType = "numberDecimal" пропонує роздільник ',' (кома), але все ж відмовляється прийняти кому. Пропоноване "." (десяткова крапка) приймається. Пройшло 9 років з моменту вперше повідомлення про цю помилку. Це якийсь запис? Кульгав.
піт

Відповіді:


105

Обхідний (поки Google не виправити цю помилку) полягає у використанні EditTextз android:inputType="numberDecimal"і android:digits="0123456789.,".

Потім додайте TextChangedListener до EditText із наступним 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
}

1
@Zoombie для показу коми (,) на клавіатурі залежить від мови, встановленої на вашому пристрої. Якщо ваш вхід має тип numberDecimal, а ваша мова - англійська (США), він відображатиметься на пристроях Nexus (довідково). Можливо, що пристрої Nexus цього не поважають
hcpl

11
Це працює, але майте на увазі, що він дозволяє пройти текст на зразок "24,22.55". Вам може знадобитися додати додаткову перевірку, щоб виправити це!
dimsuz

8
Це все-таки шлях?
Віллі Менцель

Ще краще використовувати char localizedSeparator = DecimalFormatSymbols.getInstance (). GetDecimalSeparator (); localizedFloatString = localizedFloatString.replace ('.', localizedSeparator);
southerton

4
Здається, це лише торгівля однією помилкою за іншою. Як було реалізовано вище, це буде працювати для локалів, які використовують замість них. ціною реверсу, який є більш поширеним у всьому світі. Налаштування @ southerton допомагає у цьому, однак ваші користувачі можуть здивуватися, коли потраплять на. і мають "a", з'являються на вході.
Нік

30

Варіант "цифрових" рішень, пропонованих тут:

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

Враховуючи роздільник місцевості.


Це найчистіша відповідь на початкове запитання. Спасибі
peter.bartos

Помістіть це в onCreate (), це шлях, ІМХО.
TechNyquist

6
Мені це подобається, але будьте обережні ... є клавіатури, які не переймаються мовою користувача, тому користувач, який не має ключа ,на своїх клавіатурах. Приклади: клавіатура Samsung (KitKat).
Браїс Габін

2
Це дозволить повторювати десяткові десяткові роздільники. Див відповідь нижче , щоб впоратися з цим: stackoverflow.com/a/45384821/6138589
Ездра Lopez

19

Наступна маска валюти коду для 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;
        }
    });

16

Це відома помилка в SDK для Android. Єдине рішення - створити власну м'яку клавіатуру. Ви можете знайти приклад реалізації тут .


15
Чи є новини через чотири роки?
Антоніо Сесто

Переживають це і в Xamarin.Forms. Культура - {se-SV}, і на цифровій панелі відображаються боти "," (десятковий роздільник) і "." (тисячний роздільник груп), але після натискання кнопки "" нічого не вводиться в текстове поле і жодна подія не піднімається
joacar

Я можу підтвердити, що помилка все ще існує.
Lensflare

зафіксовано в попередньому перегляді розробника Android O
R00We

6

Відповідь Мартіна не буде працювати, якщо ви створюєте екземпляр EditText програмно. Я пішов вперед і змінив включений DigitsKeyListenerклас з API 14, щоб забезпечити як коску, так і період у вигляді десяткового роздільника.

Для того, щоб використовувати цю функцію , виклик setKeyListener()на EditText, наприклад ,

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

Тим не менш, ви все одно повинні використовувати фокус Мартіна в TextChangedListener коли ви замінюєте коми на періоди

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

від doc: KeyListener слід використовувати лише у випадках, коли програма має власну екранну клавіатуру, а також хоче обробити події жорсткої клавіатури, щоб відповідати їй. developer.android.com/reference/android/text/method/…
Loda

6

ви можете використовувати наступне для різних локалів

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

Це найкраще рішення для мене, але існують проблеми з деякими телефонами, наприклад, Samsung, які не показують кома "" "на клавіатурі. Тож я змінив це, щоб дозволити як кома, так і крапку, але потім замінивши відповідно локаль
Ріккардо Касатта

5

Ви можете використовувати наступне рішення, щоб також включити кому як дійсний вхід: -

Через XML:

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

Програмно:

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

Таким чином система Android покаже клавіатуру цифр і дозволить вводити коми. Сподіваюся, що це відповідає на питання :)


За допомогою цього рішення, коли ви натискаєте ",", але редагувати текст показувати ".
Мара Хіменес

2

Для рішень Mono (Droid):

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

1

Ви можете зробити наступне:

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

І тоді ви можете використовувати вхідний фільтр:

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

}


може бути пробіл між тисячею і сотнею, цей шаблон відмовиться від форматованого введення
Ерік Чжао

1

ІМХО найкращим підходом до цієї проблеми є просто використання 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)});

Це спрацювало як шарм, дякую! (після стільки неправильного рішення вище ... :() Але у мене є питання: як я можу досягти того, щоб кома (",") відображалася на екрані не крапкою ("."), тому що в Угорщині ми використовуємо косу як десятковий роздільник. .
Абігейл Ла'Фей

1
android: digits = "0123456789", налаштування можна додати в EditText. Більше того, замість того, щоб повернути null в DecimalDigitsInputFilter, ви можете повернути source.replace (".", ",") Відповідно до відповіді stackoverflow.com/a/40020731/1510222 , не можна приховати крапку в стандартній клавіатурі
Аркадіуш Цеслінський

1

щоб локалізувати ваше введення:

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

а потім додайте:

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

ніж не забудьте замінити "," на ". тому Float або Double можуть аналізувати його без помилок.


1
Це рішення дозволяє вводити кілька коми
Лео Дродікодер

1

Усі інші пости тут мали великі дірки, тож ось таке рішення, яке буде:

  • Примусове застосування коми або періодів на основі регіону не дозволить ввести протилежне.
  • Якщо EditText починається з якогось значення, він замінює правильний роздільник за потребою.

У XML:

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

Змінна класу:

private boolean isDecimalSeparatorComma = false;

У програмі onCreate знайдіть роздільник, який використовується у поточній локалі:

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(",");
    }
}

Також onCreate, використовуйте це для оновлення, якщо ви завантажуєте поточне значення:

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

Також onCreate, додайте слухачів

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

Приклад doSomething (), перетворити на стандартний період для обробки даних

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

0

Android має вбудований формат чисел.

Ви можете додати це в ваших , EditTextщоб дозволити знаків після коми і ком: android:inputType="numberDecimal"іandroid:digits="0123456789.,"

Потім десь у вашому коді, коли користувач натискає кнопку "Зберегти" або після введення тексту (використовуйте слухач).

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

0

Я вирішив змінити кому на крапку лише під час редагування. Ось мій складний і відносно простий спосіб вирішення:

    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 буде використовувати кому або крапку залежно від Locale


0

Я не знаю, чому ваші відповіді такі складні. Якщо в SDK є помилка, ви повинні її замінити або обійти.

Я обрав другий спосіб вирішення цієї проблеми. Якщо ви відформатуєте рядок як Locale.ENGLISHі потім помістіть його до EditText(навіть як порожній рядок). Приклад:

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

Отримавши рішення, ваш результат сумісний із показаною клавіатурою. Потім флоат і подвійні числа працюють в типовому для мов програмування способі з крапкою, а не комою.


0

Моє рішення:

  • Основна діяльність:

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

  • У файлі xml: android:imeOptions="flagNoFullscreen" android:inputType="numberDecimal"

і я взяв дубль у editText як струну.


0

Я можу підтвердити, що запропоновані виправлення не працюють на Samsung IME (принаймні, на S6 та S9) та, можливо, на LG. Вони як і раніше показують крапку як десятковий роздільник незалежно від місцевості. Перехід на IME Google виправляє це, але навряд чи це варіант для більшості розробників.

Це також не було зафіксовано в Oreo для цих клавіатур, оскільки це виправлення, яке повинні зробити Samsung та / або LG, а потім натиснути навіть на свої старовинні телефони.

Я замість цього розіграв проект клавіатури з цифровою клавіатурою і додав режим, коли він поводиться як IME: fork . Деталі див. У зразку проекту. Для мене це спрацювало досить добре і схоже на багато підроблених IME, що вводяться в PIN-коді, які ви бачите в банківських програмах.

Зразок скріншота програми


0

Минуло більше 8 років, і я здивований, ця проблема ще не виправлена ​​...
Я боровся з цією простою проблемою, оскільки найвідповідальніша відповідь @Martin дозволяє вводити кілька роздільників, тобто користувач може вводити "12 ,,, ,,, 12,1,, 21,2, "
Також, друга проблема полягає в тому, що на деяких пристроях кома не відображається на цифровій клавіатурі (або вимагає багаторазового натискання кнопкової точки)

Ось мій спосіб вирішення, який вирішує згадані проблеми та дозволяє користувачеві вводити текст '.' і ',', але в EditText він побачить єдиний десятковий роздільник, який відповідає поточній мові:

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

І спостерігач тексту:

  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(""))
        }
    }
}

0

Просте рішення, зробіть спеціальний контроль. (це зроблено в Android Xamarin, але він повинен легко переходити на 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);
            }

        }
    }
}

0

Ви можете використовувати inputType="phone", проте в такому випадку вам доведеться мати справу з декількома ,або .наявними, тому буде потрібна додаткова перевірка.


-1

Я думаю, що це рішення менш складне, ніж інші написані тут:

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

Таким чином, коли ви натискаєте "." в м'якій клавіатурі нічого не відбувається; дозволяються лише цифри і кома.


4
якщо ви це зробите, ви просто зламаєте всі локалі, які використовують '.' замість цього.
Нік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.