【问题标题】: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?如何验证android中的编辑文本,使其最多可以包含6位数字和小数点后2位数字?
【发布时间】:2014-02-23 10:34:50
【问题描述】:

好吧,我的要求是在编辑文本中添加过滤器,使其可以包含最多 6 位和小数点后 2 位的最大值。我基本上需要的是允许用户最多输入 6 位小数点后最多2位。

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)

现在在谷歌上搜索了一段时间后,我找到了使用 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;
    }
}

现在上面的代码抛出以下错误

Java 堆栈溢出错误

我错过了什么?

【问题讨论】:

    标签: android validation android-edittext textwatcher


    【解决方案1】:

    我认为您的问题是您尝试在 public void afterTextChanged(Editable s) 中再次设置 EditText,因为 case 输入无效。

    如果您在 afterTextChanged 中更改文本,那么另一个 afterTextChanged 将被一遍又一遍地调用,就像您在 logcat 中看到的那样

    另请参阅documentation for afterTextChanged,他们确实警告可能在那里创建无限循环:

    调用此方法是为了通知您,在 s 中的某处,文本已更改。从这个回调中对 s 进行进一步的更改是合法的,但请注意不要让自己陷入无限循环,因为您所做的任何更改都会导致再次递归调用此方法

    【讨论】:

    • 嘿,如果我将三元条件更改如下: mText = isValid(s) ?年代:“”;一切正常。
    • 尝试在 isValid 方法中记录您尝试验证的 CharSequence。也许这不是你所期望的。
    【解决方案2】:

    如果您只想允许小数点前 6 位和小数点后 2 位,则无需添加 addTextChangedListener 如果您只需要 8 位(或者 beforeDecimal = 6, afterDecimal = 2 (或) beforeDecimal = 8, afterDecimal = 0 你可以使用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;
                }
            }
    

    【讨论】:

      猜你喜欢
      • 2016-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多