How do I validate an edit text in android so that it can contain 6 digits and 2 digits after a decimal point at most?

StackOverflow https://stackoverflow.com/questions/21967112

Domanda

Well my requirement is to add filters in an edit text in such a manner that it can contain maximum value upto 6 digits and 2 digits after the decimal point.Well what I basically need is to allow users to input 6 digits at most and 2 digits after the decimal point at most .

For example 

999999.99 is valid (6 digits and two digits after the decimal)

9999999 is not valid (& digits)

999.99 is valid (3 digits and 2 digits after the decimal place)

Now after googling for a while I found a solution to my problem with the following piece of code using TextWatcher

public static CharSequence validText ="";

    public static EditText setAmountValidation(final EditText editText,final Context context){

        editText.addTextChangedListener(new TextWatcher() 
        {           

           private final Pattern sPattern  = Pattern.compile("^([1-9][0-9]{0,5})?(\\.[0-9]{0,2}?)?$");

            private  CharSequence mText="";


            private boolean isValid(CharSequence s) {
                return sPattern.matcher(s).matches();
            }

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

            }           

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

                if(isValid(s)){
                    validText= s;

                }

                mText = isValid(s) ? s : validText;


            }           

            @Override
            public void afterTextChanged(Editable s) 
            {
                if (!isValid(s))
                {

                    editText.setText(mText);
                }
                mText = "";
            }
        });

        return editText;
    }
}

Now the code above throws the following error

Java stackoverflowerror

What is it that I am missing ?

È stato utile?

Soluzione

I think your problem is that you are trying to set the EditText again in your public void afterTextChanged(Editable s) for the case inputs are not valid.

if you change text in afterTextChanged then another afterTextChanged will be called over and over again like you can see in logcat

See also documentation for afterTextChanged they do warn about possible creation of infinite loops there:

This method is called to notify you that, somewhere within s, the text has been changed. It is legitimate to make further changes to s from this callback, but be careful not to get yourself into an infinite loop, because any changes you make will cause this method to be called again recursively

Altri suggerimenti

If you want to allow only 6 digits before decimal and 2 digits after decimal you no need to add addTextChangedListener if you want only 8 digit (either beforeDecimal = 6, afterDecimal = 2 (or) beforeDecimal = 8, afterDecimal = 0 you can use addTextChangedListener.

EditText tv;

tv = (EditText) findViewById(R.id.test_value);

int beforeDecimal = 6, afterDecimal = 2;


tv.setFilters(new InputFilter[] { new DigitsKeyListener(Boolean.FALSE,
            Boolean.TRUE) {

        @Override

        public CharSequence filter(CharSequence source, int start, int end,
                Spanned dest, int dstart, int dend) {

            String etText = tv.getText().toString();

            if (etText.isEmpty()) {

                return null;
            }
            String temp = tv.getText() + source.toString();

            if (temp.equals(".")) {

                return "0.";

            } else if (temp.toString().indexOf(".") == -1) {

                if (temp.length() > beforeDecimal) {

                    return "";
                }
            } else {

                int dotPosition;

                int cursorPositon = tv.getSelectionStart();

                if (etText.indexOf(".") == -1) {

                    dotPosition = temp.indexOf(".");
                } else {

                    dotPosition = etText.indexOf(".");
                }
                if (cursorPositon <= dotPosition) {

                    String beforeDot = etText.substring(0, dotPosition);

                    if (beforeDot.length() < beforeDecimal) {
                        return source;

                    } else {
                        if (source.toString().equalsIgnoreCase(".")) {

                            return source;
                        } else {

                            return "";
                        }
                    }
                } else {
                    temp = temp.substring(temp.indexOf(".") + 1);

                    if (temp.length() > afterDecimal) {

                        return "";
                    }
                }
            }
            return super.filter(source, start, end, dest, dstart, dend);

        }
    } });

    tv.addTextChangedListener(new TextWatcher() {

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

            String temp = tv.getText() + s.toString();

            if (temp.contains(".")) {

                beforeDecimal = 6; /***6 Digits beforedecimal and 2 after decimal****/

                afterDecimal = 2;
            } else {

                beforeDecimal = 8;  /***8 Digits beforedecimal and 0 after decimal***/

                afterDecimal = 0;
            }
        }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top