Десятковий комір роздільника (',') з числом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.