EditText输入限制:整数,小数,最大值,最大字符长度,手机号

来源:互联网 发布:太阳系比较模拟软件 编辑:程序博客网 时间:2024/05/17 03:22

EditText是最常用的控件。很多情况下都要求只能输入特定的字符。比如只能输入整数,只能输入两位小数等。

为了满足EditText输入限制,大体上有两种方法:
- 给EditText加TextWatcher,监听用户输入,如果输入不合法,作相应处理。
- 使用InputFilter。

两种方法都能实现,但感觉第一种方式不太好复用。考虑使用InputFilter的实现。

InputFilters can be attached to Editables to constrain the changes that can be made to them.
(InputFilters可以限制可输入控件的输入)

EditText继承TextView,TextView中有个setFilters方法,这个方法就是设置InputFilters的。需要注意的是,这个方法最好只调用一次,多次调用,只有最后一次才会生效(即会覆盖之前的操作)。

在实际使用中,只要实现InputFilter类,满足各种各样的输入限制就行了。InputFilter只有一个filter方法要实现。该方法有五个参数:
- CharSequence source:刚输入的还没显示出来的字符
- int start与int end:应该是输入字符的位置,输入一个字符时分别是0和1,删除时都是0.
- Spanned dest:已经在EditText中显示出来的字符。
- int dstart, int dend:输入字符要插入和删除的位置。

实现了一个XEditText类,该类继承自AppCompatEditText,实现了多个InputFilter满足输入限制的功能。

import android.content.Context;import android.support.v7.widget.AppCompatEditText;import android.text.InputFilter;import android.text.Spanned;import android.text.TextUtils;import android.util.AttributeSet;import java.util.ArrayList;import java.util.List;import java.util.regex.Pattern;/** * Created by 林下de夕阳 on 2017/4/28. * 具有输入限制的EditText */public class XEditText extends AppCompatEditText {    // 保存设置的所有输入限制    private List<InputFilter> inputFilters;    public XEditText(Context context) {        super(context);        init();    }    public XEditText(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public XEditText(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    private void init() {        inputFilters = new ArrayList<>();    }    /**     * 设置允许输入的最大字符数     */    public void setMaxLengthFilter(int maxLength) {        inputFilters.add(new InputFilter.LengthFilter(maxLength));        setFilters(inputFilters.toArray(new InputFilter[inputFilters.size()]));    }    /**     * 设置可输入小数位     */    public void setDecimalFilter(int num) {        inputFilters.add(new SignedDecimalFilter(0, num));        setFilters(inputFilters.toArray(new InputFilter[inputFilters.size()]));    }    /**     * 设置最大值     * @param maxmum  允许的最大值     * @param numOfDecimal  允许的小数位     */    public void setMaxmumFilter(double maxmum, int numOfDecimal) {        inputFilters.add(new MaxmumFilter(0, maxmum, numOfDecimal));        setFilters(inputFilters.toArray(new InputFilter[inputFilters.size()]));    }    /**     * 设置只能输入整数     * @param min 输入整数的最小值     */    public void setIntergerFilter(int min) {        inputFilters.add(new SignedIntegerFilter(min));        setFilters(inputFilters.toArray(new InputFilter[inputFilters.size()]));    }    /**     * 只能够输入手机号码     */    public void setTelFilter() {        inputFilters.add(new TelephoneNumberInputFilter());        setFilters(inputFilters.toArray(new InputFilter[inputFilters.size()]));    }    /**     * 小数位数限制     */    private static final class SignedDecimalFilter implements InputFilter {        private final Pattern pattern;        SignedDecimalFilter(int min, int numOfDecimals) {            pattern = Pattern.compile("^" + (min < 0 ? "-?" : "")                    + "[0-9]*\\.?[0-9]" + (numOfDecimals > 0 ? ("{0," + numOfDecimals + "}$") : "*"));        }        @Override        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {            if (source.equals(".")) {                if (dstart == 0 || !(dest.charAt(dstart - 1) >= '0' && dest.charAt(dstart - 1) <= '9') || dest.charAt(0) == '0') {                    return "";                }            }            if (source.equals("0") && (dest.toString()).contains(".") && dstart == 0) { //防止在369.369的最前面输入0变成0369.369这种不合法的形式                return "";            }            StringBuilder builder = new StringBuilder(dest);            builder.delete(dstart, dend);            builder.insert(dstart, source);            if (!pattern.matcher(builder.toString()).matches()) {                return "";            }            return source;        }    }    /**     * 限制输入最大值     */    private static final class MaxmumFilter implements InputFilter {        private final Pattern pattern;        private final double maxNum;        MaxmumFilter(int min, double maxNum, int numOfDecimals) {            pattern = Pattern.compile("^" + (min < 0 ? "-?" : "")                    + "[0-9]*\\.?[0-9]" + (numOfDecimals > 0 ? ("{0," + numOfDecimals + "}$") : "*"));            this.maxNum = maxNum;        }        @Override        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {            if (source.equals(".")) {                if (dstart == 0 || !(dest.charAt(dstart - 1) >= '0' && dest.charAt(dstart - 1) <= '9') || dest.charAt(0) == '0') {                    return "";                }            }            if (source.equals("0") && (dest.toString()).contains(".") && dstart == 0) {                return "";            }            StringBuilder builder = new StringBuilder(dest);            builder.delete(dstart, dend);            builder.insert(dstart, source);            if (!pattern.matcher(builder.toString()).matches()) {                return "";            }            if (!TextUtils.isEmpty(builder)) {                double num = Double.parseDouble(builder.toString());                if (num > maxNum) {                    return "";                }            }            return source;        }    }    /**     * 限制整数     */    private static final class SignedIntegerFilter implements InputFilter {        private final Pattern pattern;        SignedIntegerFilter(int min) {            pattern = Pattern.compile("^" + (min < 0 ? "-?" : "") + "[0-9]*$");        }        @Override        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {            StringBuilder builder = new StringBuilder(dest);            builder.insert(dstart, source);            if (!pattern.matcher(builder.toString()).matches()) {                return "";            }            return source;        }    }    /**     * 限制电话号码     */    private static class TelephoneNumberInputFilter implements InputFilter {        @Override        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {            StringBuilder builder = new StringBuilder(dest);            builder.insert(dstart, source);            int length = builder.length();            if (length == 1) {                if (builder.charAt(0) == '1') {                    return source;                } else {                    return "";                }            }            if (length > 0 && length <= 11) {                int suffixSize = length - 2;                Pattern pattern = Pattern.compile("^1[3-9]\\d{" + suffixSize + "}$");                if (pattern.matcher(builder.toString()).matches()) {                    return source;                } else {                    return "";                }            }            return "";        }    }}
1 0