限制EditText内容为.2位小数,支持最大值最小值和负数

版权声明:本文为博主原创文章,未经博主允许不得转载。 - long for us https://blog.csdn.net/longforus/article/details/71214817
tv_result.setInputType(InputType.TYPE_CLASS_TEXT);
            tv_result.setMaxLines(mBean.getFeildType().equals("2") ? 10 : 1);
            switch (mBean.getDataType()) {
                case "2":
                    tv_result.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
                    break;
                case "3":
                    tv_result.setInputType(InputType.TYPE_CLASS_PHONE);
                    break;
                case "4":
                    tv_result.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
                    break;
                case "5"://纯数字
                    tv_result.setInputType(InputType.TYPE_NUMBER_FLAG_SIGNED);
                    break;
                case "6"://百分比
                    tv_result.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
                    break;
            }

            tv_result.setOnFocusChangeListener((v, hasFocus) -> {
                if (!hasFocus) {
                    String trim = tv_result.getText().toString().trim();
                  if (mBean.getDataType().equals("6")) {
                        dispose6(trim);
                    } else {
                        mBean.resultContent = trim;
                    }
                }
            });
            if (!mBean.isSelect()) {
                mWatcher = 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) {
                        if (mBean.getDataType().equals("6")) {
                            dispose6(s);
                        } else {
                            mBean.resultContent = s.toString().trim();
                        }
                    }

                    @Override
                    public void afterTextChanged(Editable edt) {
                        if (mBean.getDataType().equals("4") || mBean.getDataType().equals("6")) {
                            String temp = edt.toString();
                            int posDot = temp.indexOf(".");
                            if (posDot <= 0) {
                                return;
                            }
                            if (temp.length() - posDot - 1 > 2) {
                                edt.delete(posDot + 3, posDot + 4);
                            }
                        }
                    }
                };
                tv_result.addTextChangedListener(mWatcher);
            } else {
                tv_result.removeTextChangedListener(mWatcher);
            }
        }


        /**
         * 限制内容为不大于100的.2位小数
         */
        private void dispose6(CharSequence s) {
            String vlaue = null;
            String trim = s.toString().trim();
            if (trim.startsWith("0")) {
                String result = trim.substring(1);
                tv_result.setText(result);
                ((EditText) tv_result).setSelection(result.length());
            }
            try {
                vlaue = String.format("%.2f", Double.parseDouble(trim));
                if (Double.valueOf(vlaue) > 100) {
                    mBean.resultContent = "100.00";
                    tv_result.setText(mBean.resultContent);
                    ((EditText) tv_result).setSelection(mBean.resultContent.length());
                } else {
                    mBean.resultContent = vlaue;
                }
            } catch (NumberFormatException e) {
                mBean.resultContent = "100.00";
            }
        }

2018-5-29 17:54:22 新增:

下面是网上找到的更优雅的实现方式,在原作的基础上添加了自动添加¥的功能:

public class CashierInputFilter implements InputFilter {
    Pattern mPattern;    
  
    //输入的最大金额    
    private static final int MAX_VALUE = Integer.MAX_VALUE;    
    //小数点后的位数    
    private static final int POINTER_LENGTH = 0;
    
    private static final String POINTER = ".";    
    
    private static final String ZERO = "0";  
  
    public CashierInputFilter() {  
        mPattern = Pattern.compile("([0-9]|\\.)*");
    }    
    
    /**  
     * @param source    新输入的字符串  
     * @param start     新输入的字符串起始下标,一般为0  
     * @param end       新输入的字符串终点下标,一般为source长度-1  
     * @param dest      输入之前文本框内容  
     * @param dstart    原内容起始坐标,一般为0  
     * @param dend      原内容终点坐标,一般为dest长度-1  
     * @return          输入内容  
     */    
    @Override    
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        String sourceText = source.toString();
        String destText = dest.toString();
        //验证删除等按键
        if (TextUtils.isEmpty(sourceText)) {
            return "";    
        }
        Matcher matcher = mPattern.matcher(source);
        //已经输入小数点的情况下,只能输入数字    
        if(destText.contains(POINTER)) {    
            if (!matcher.matches()) {    
                return "";    
            } else {    
                if (POINTER.equals(source.toString())) {  //只能输入一个小数点  
                    return "";    
                }    
            }    
    
            //验证小数点精度,保证小数点后只能输入两位    
            int index = destText.indexOf(POINTER);    
            int length = dend - index;    
    
            if (length > POINTER_LENGTH) {    
                return dest.subSequence(dstart, dend);  
            }    
        } else {  
            /** 
             * 没有输入小数点的情况下,只能输入小数点和数字 
             * 1. 首位不能输入小数点 
             * 2. 如果首位输入0,则接下来只能输入小数点了 
             */  
            if (!matcher.matches()) {    
                return "";    
            } else {    
                if ((POINTER.equals(source.toString())) && TextUtils.isEmpty(destText)) {  //首位不能输入小数点  
                    return "";  
                } else if (!POINTER.equals(source.toString()) && ZERO.equals(destText)) { //如果首位输入0,接下来只能输入小数点  
                    return "";  
                }  
            }    
        }    
    
        //验证输入金额的大小  
        String result = destText + sourceText;
        result =result.replaceAll("¥","");
        double sumText = Double.parseDouble(result);
        if (sumText > MAX_VALUE) {    
            return dest.subSequence(dstart, dend);
        }
        if (destText.startsWith("¥")) {
            return dest.subSequence(dstart, dend) + sourceText;
        } else {
            return "¥"+dest.subSequence(dstart, dend) + sourceText;
        }
    }
}  

在实现自动添加¥的功能的时候还发现在限制 

android:inputType="numberDecimal"

的时候,数字之外的字符是不会显示的,¥也不会显示,不限制输入类型为小数呢也不符合需求,后来经偶像大牛大飞哥的提醒.在xml中

android:digits="0123456789.¥"

再加入digits的限制,问题就解决了,大飞哥是真的强.

2018-8-24 11:01:46 新增支持最大最小值限定和负数:

public class CashierInputFilter implements InputFilter {
    //小数点后的位数
    private static final int    POINTER_LENGTH = 2;
    private static final String POINTER        = ".";
    private static final String ZERO           = "0";
    private Pattern mPattern;
    //输入的最大金额
    private double mMaxValue = Double.MAX_VALUE;
    private double mMinValue = 0f;

    public CashierInputFilter(double maxValue) {
        mMaxValue = maxValue;
        init();
    }

    public void init() {
        if (mMinValue == 0) {
            mPattern = Pattern.compile("([0-9]|\\.)*");
        } else {
            mPattern = Pattern.compile("([-]?[0-9]?|\\.)*");
        }
    }

    public CashierInputFilter(double maxValue, double minValue) {
        mMaxValue = maxValue;
        mMinValue = minValue;
        init();
    }

    /**
     * @param source 新输入的字符串
     * @param start 新输入的字符串起始下标,一般为0
     * @param end 新输入的字符串终点下标,一般为source长度-1
     * @param dest 输入之前文本框内容
     * @param dstart 原内容起始坐标,一般为0
     * @param dend 原内容终点坐标,一般为dest长度-1
     * @return 输入内容
     */
    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        String sourceText = source.toString();
        String destText = dest.toString();
        //验证删除等按键
        if (TextUtils.isEmpty(sourceText)) {
            return "";
        }

        Matcher matcher = mPattern.matcher(source);
        //已经输入小数点的情况下,只能输入数字
        if (destText.contains(POINTER)) {
            if (!matcher.matches()) {
                return "";
            } else {
                if (POINTER.equals(source.toString())) {  //只能输入一个小数点
                    return "";
                }
            }

            //验证小数点精度,保证小数点后只能输入两位
            int index = destText.indexOf(POINTER);
            int length = dend - index;

            if (length > POINTER_LENGTH) {
                return dest.subSequence(dstart, dend);
            }
        } else {
            /**
             * 没有输入小数点的情况下,只能输入小数点和数字
             * 1. 首位不能输入小数点
             * 2. 如果首位输入0,则接下来只能输入小数点了
             */
            if (!matcher.matches()) {
                return "";
            } else {
                if ((POINTER.equals(source.toString())) && TextUtils.isEmpty(destText)) {  //首位不能输入小数点
                    return "";
                } else if (!POINTER.equals(source.toString()) && ZERO.equals(destText)) { //如果首位输入0,接下来只能输入小数点
                    return "";
                }
            }
        }

        //验证输入金额的大小
        String result = destText + sourceText;
        if (mMinValue < 0 && "-".equals(result)) {
            return result;
        }
        double sumText = Double.parseDouble(result);
        if (sumText > mMaxValue||sumText<mMinValue) {
            return dest.subSequence(dstart, dend);
        }
        return dest.subSequence(dstart, dend) + sourceText;
    }
}

猜你喜欢

转载自blog.csdn.net/longforus/article/details/71214817
今日推荐