Ввод денег Android с фиксированным десятичным числом

Как вы создаете запись edittext, которая форматирует ввод только в денежном формате? Когда пользователь вводит 5, я хочу, чтобы ввод выглядел как «0,05 доллара», а когда он затем вводит 3, ввод теперь должен выглядеть как «0,53 доллара», и, наконец, он вводит 6, а ввод должен выглядеть как «5,36 доллара».


person miannelle    schedule 10.06.2010    source источник


Ответы (7)


Полное решение ninjasense в основном работает, но у него есть некоторые проблемы:

  1. Каждый раз, когда данные поля изменяются в обработчике onTextChanged, позиция курсора сбрасывается до индекса 0 в поле, что немного раздражает при вводе денежных значений.
  2. Он использует числа с плавающей запятой для форматирования денежных значений, что может иметь неприятные последствия.

Для первой проблемы у меня еще нет решения, для второй работает такой код:

    @Override
    public void onTextChanged(CharSequence s, int start,
            int before, int count) {
        if(!s.toString().matches("^\\$(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$"))
        {
            String userInput= ""+s.toString().replaceAll("[^\\d]", "");
            StringBuilder cashAmountBuilder = new StringBuilder(userInput);

            while (cashAmountBuilder.length() > 3 && cashAmountBuilder.charAt(0) == '0') {
                cashAmountBuilder.deleteCharAt(0);
            }
            while (cashAmountBuilder.length() < 3) {
                cashAmountBuilder.insert(0, '0');
            }
            cashAmountBuilder.insert(cashAmountBuilder.length()-2, '.');
            cashAmountBuilder.insert(0, '$');

            cashAmountEdit.setText(cashAmountBuilder.toString());
        }

    }
person Zds    schedule 04.03.2011

Строительство Zds.

Используйте это для удержания курсора в конце поля.

cashAmountEdit.setTextKeepState(cashAmountBuilder.toString());
Selection.setSelection(cashAmountEdit.getText(), cashAmountBuilder.toString().length());
person rozsnyai    schedule 23.03.2011

Вы можете использовать TextWatcher, чтобы делать такие вещи.

Расширение TextWatcher: http://d.android.com/reference/android/text/TextWatcher.html

public class MyTextWatcher implements TextWatcher {

    public void afterTextChanged(Editable arg0) { 

    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

    }

    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

}

Затем добавьте его в свой editText с помощью

myEditText.addTextChangedListener(new MyTextWatcher());
person m6tt    schedule 10.06.2010

Я нашел TextWatcher немного громоздким. Вместо этого вы можете установить прослушиватель ключей:

setKeyListener(new CalculatorKeyListener());
// Must be called after setKeyListener(), otherwise is overridden
setRawInputType(Configuration.KEYBOARD_12KEY);

А затем создайте KeyListener, который расширяет NumberKeyListener:

class CalculatorKeyListener extends NumberKeyListener {
    @Override
    public int getInputType() {
        return InputType.TYPE_CLASS_NUMBER;
    }

    @Override
    public boolean onKeyDown(View view, Editable content, int keyCode, KeyEvent event) {
        if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
            digitPressed(keyCode - KeyEvent.KEYCODE_0);
        } else if (keyCode == KeyEvent.KEYCODE_DEL) {                                         
            deletePressed();
        }
        return true;
    }

    @Override
    protected char[] getAcceptedChars() {
        return new char[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    }
}

Затем вам нужно правильно отобразить символы, но это несложно; просто следите за центами, а затем разделите или умножьте на 10 и используйте NumberFormat, чтобы получить правильное форматирование.

person Shawn Lauzon    schedule 30.12.2010
comment
KeyListener больше не работает на некоторых устройствах, см. это примечание: Нажатие клавиш на методах мягкого ввода не требуется для запуска методов в этом прослушивателе, и на самом деле это не рекомендуется. Клавиатура Android по умолчанию не будет запускать их для любой клавиши любого приложения, предназначенного для Jelly Bean или более поздней версии, и будет доставлять их только для некоторых нажатий клавиш для приложений, предназначенных для Ice Cream Sandwich или более ранней версии. Источник: developer.android.com/reference/android/text/method/ - person Dan Osipov; 10.09.2012

Вот мое полное решение:

                tvValue.setRawInputType(Configuration.KEYBOARD_12KEY);

            tvValue.addTextChangedListener(new TextWatcher(){


                @Override
                public void afterTextChanged(Editable arg0) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void beforeTextChanged(CharSequence s, int start,
                        int count, int after) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onTextChanged(CharSequence s, int start,
                        int before, int count) {
                    // TODO Auto-generated method stub

                    // here i converted to string
                    if(!s.toString().matches("^\\$(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$"))
                    {
                        String userInput= ""+s.toString().replaceAll("[^\\d]", "");
                        Float in=Float.parseFloat(userInput);
                        float percen = in/100;
                        tvValue.setText("$"+percen);
                    }

                }

            });
person ninjasense    schedule 21.02.2011

Я сделал это, но без десятичных знаков и с точкой для миль, проверьте код и добавьте функциональность для поддержки десятичных знаков.

    MyEditText.addTextChangedListener(new TextWatcher() 
        {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count){
                if(s.toString().length() > 0){
                    MyEditText.removeTextChangedListener(this);                 
                    String numbers = removeCharacters(s.toString());
                    int money = 0;
                    try{
                        money = Integer.parseInt(numbers);
                    }
                    catch(Exception ex){
                        money = 0;
                    }

                    MyEditText.setText(getMoney(money));
                    //Set cursor on correct position
                    int selection = start;
                    if(count > 0){
                        selection++;
                        if(MyEditText.getText().toString().length() == 2 || MyEditText.getText().toString().length() == 6 || MyEditText.getText().toString().length() == 10){
                            selection++;
                        }                           
                    }
                    else{
                        if(MyEditText.getText().toString().length() == 4 || MyEditText.getText().toString().length() == 8){
                            selection--;
                        }
                    }

                    if(selection > MyEditText.getText().toString().length()){
                        selection = MyEditText.getText().toString().length();
                    }                       

                    MyEditText.setSelection(selection);
                    MyEditText.addTextChangedListener(this);
                }
                if(s.toString().length() == 1 && count < 1 && start == 1){
                    MyEditText.removeTextChangedListener(this);
                    MyEditText.setText("");
                    MyEditText.addTextChangedListener(this);
                }

            }           

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after){

            }           

            @Override
            public void afterTextChanged(Editable s) 
            {

            }

        });



    public String removeCharacters(String money){       

    int i=0;
    while (i<money.length())
    {
        Character c = money.charAt(i);          
            if (Character.isDigit(c) && c != '.')
            {               
                i++;
            }
            else
            {               
                money = money.replace(c.toString(), "");                
            }
    }

    return money;
}


public String getMoney(int value){
    String money = "$";
    NumberFormat numberFormatter;       
    numberFormatter = NumberFormat.getNumberInstance(Locale.GERMAN);        
    money += numberFormatter.format(value);

    return money;
}
person Sergio Ramirez    schedule 19.12.2013

Этот ответ основан на ответе Zds (который, в свою очередь, основан на ответ ninjasense), но это должно решить проблему с положением курсора:

if(!text.matches("^\\$(\\d{1,2})(\\.\\d{2})?$")) {
    int originalCursorPosition = view.getSelectionStart();
    int cursorOffset = 0;

    boolean cursorAtEnd = originalCursorPosition == text.length();

    String userInput= ""+text.replaceAll("[^\\d]", "");
    StringBuilder cashAmountBuilder = new StringBuilder(userInput);

    while (cashAmountBuilder.length() > 3 && cashAmountBuilder.charAt(0) == '0')           {  
        cashAmountBuilder.deleteCharAt(0);
        cursorOffset--;
    }
    while (cashAmountBuilder.length() < 3) {
        cashAmountBuilder.insert(0, '0');
        cursorOffset++;
    }
    cashAmountBuilder.insert(cashAmountBuilder.length() - 2, '.');
    cashAmountBuilder.insert(0, '$');

    view.setText(cashAmountBuilder.toString());
    view.setSelection(cursorAtEnd ? view.getText().length() : originalCursorPosition + cursorOffset);
}

Примечания:

  • Следующее находится в TextWatcher.onTextChanged
  • Я использую регулярное выражение, отличное от других ответов, что удерживает цену на уровне ‹ 100 долларов.
  • 'view' - это editText, 'text' - это содержимое строки
  • это сработало для меня, используя EditText с maxLength из 6 (т.е. 00,00 долларов США)
person Squimon    schedule 05.08.2015