Android Money Input with fixed decimal

后端 未结 7 1235
鱼传尺愫
鱼传尺愫 2020-12-02 00:07

How do you create an edittext entry that formats input in money format only? When the user enters 5, I want the input to look like \"$0.05\" and when they then enter 3, th

相关标签:
7条回答
  • 2020-12-02 00:16

    You can use a TextWatcher to do that kind of thing.

    Extend 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) {
    
        }
    
    }
    

    Then add it to your editText with

    myEditText.addTextChangedListener(new MyTextWatcher());
    
    0 讨论(0)
  • 2020-12-02 00:20

    ninjasense's complete solution basically works, but it has some issues:

    1. Every time the data of the field is altered in the "onTextChanged" handler, cursor position resets to index 0 on the field, which is a bit annoying to happen when typing in monetary values.
    2. It uses floats for formatting monetary values, which can backfire.

    For the first problem I don't have solution yet, for the second one code like this works:

        @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());
            }
    
        }
    
    0 讨论(0)
  • 2020-12-02 00:29

    I found the TextWatcher to be a bit cumbersome. Instead, you can set the key listener:

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

    And then create a KeyListener which extends 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 };
        }
    }
    

    You then need to display the characters correctly, but that's not difficult; just keep track of cents, and then divide or multiply by 10, and use a NumberFormat to get the formatting correct.

    0 讨论(0)
  • 2020-12-02 00:35

    I did this but without decimal and with dot for miles, check the code and add the functionality to support decimals.

        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;
    }
    
    0 讨论(0)
  • 2020-12-02 00:37

    Building off Zds.

    For keeping the cursor positioned at the end of the field use this.

    cashAmountEdit.setTextKeepState(cashAmountBuilder.toString());
    Selection.setSelection(cashAmountEdit.getText(), cashAmountBuilder.toString().length());
    
    0 讨论(0)
  • 2020-12-02 00:37

    Heres my complete solution:

                    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);
                        }
    
                    }
    
                });
    
    0 讨论(0)
提交回复
热议问题