/**
 * @author :
 * @date:2018/12/18
 */

public class CEditText extends EditText {
    private static final String DEFAULT_MAX_MONEY_VALUE = \"^[\\\\d]{1,numSize}([.][\\\\d]{0,maxDecimalSize})?$\";
    private static final String DEFAULT_LIMIT_DECIMAL = \"^[\\\\d]([.][\\\\d]{0,maxDecimalSize})?$\";
    private static final String DEFAULT_LIMIT_NUM = \"^[\\\\d]{1,numSize}([.][\\\\d])?$\";
    /**
     * 汉字正则表达式
     */
    private static final String CHINE_SWORD = \"^[\\\\u4e00-\\\\u9fa5]+$\";
    /**
     * 换行回车正则表达式
     */
    public static final String ENTER_REGEX = \"(.*((\\\\r+)|(\\\\n+)|(\\\\r\\\\n)+|(\\\\n\\\\r)+).*)\";

    /**
     * 邮箱
     */
    public static final String EMAIL_REGEX =
            \"^[a-zA-Z0-9][\\\\w\\\\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\\\\w\\\\.-]*[a-zA-Z0-9]\\\\.[a-zA-Z][a-zA-Z\\\\.]*[a-zA-Z]$\";

    /**
     * 空格正则表达式
     */
    public static final String SPACE_REGEX = \" \";

    /**
     * 字母和数字正则表达式
     */
    public static final String EN_NUMBER = \"^[A-Za-z0-9]$\";
    /**
     * 身份证
     */
    public static final String ID_CARD_REG = \"^(\\\\d{15}$|^\\\\d{18}$|^\\\\d{17}(\\\\d|X|x))$\";
    /**
     * 手机号码
     */
    public static final String PHONE_REGEX = \"^(1[3456789][0-9]{9})$\";

    //中文和点
    public static final String REGEX_CHINESE_NAME = \"^[•·..\\\\u4e00-\\\\u9fa5]+$\";

    /**
     * 中文,数字和英文
     */
    public static final String REGEX_ZH_NB_EN = \"^[A-Za-z0-9\\\\u4e00-\\\\u9fa5]+$\";
    private boolean isOnlyInputNumber; //只能输入整数
    private boolean isOnlyInputDecimal; //输入整数和小数
    private boolean isOnlyInputChinese;  //只能中文
    private boolean isOnlyInputNumEn;  //只能输入数字和英文
    private boolean isOnlyInputEmail;
    private boolean isOnlyInputPhone;
    private boolean isOnlyInputIdCard;
    private boolean isOnlyInputChinesed;
    private boolean isOnlyInputChEnNum;
    private int maxNumberSize;  //整数部分最大位数
    private int maxDecimalSize; //小数部分最大位数
    private int maxInputSize;   //输入的最大长度
    private boolean canInputSpace;
    private boolean canInputEnter;
    private boolean canInputEmoji;
    private List<InputFilter> inputFilters;

    public CEditText(Context context) {
        super(context);
    }

    public CEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CEditText);
        init(array);
    }

    public CEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CEditText);
        init(array);
    }

    private void init(TypedArray arrays) {
        isOnlyInputNumber = arrays.getBoolean(R.styleable.CEditText_isOnlyInputNumber, false);
        isOnlyInputDecimal = arrays.getBoolean(R.styleable.CEditText_isOnlyInputDecimal, false);
        isOnlyInputChinese = arrays.getBoolean(R.styleable.CEditText_isOnlyInputChinese, false);
        isOnlyInputNumEn = arrays.getBoolean(R.styleable.CEditText_isOnlyInputNumEn, false);
        isOnlyInputEmail = arrays.getBoolean(R.styleable.CEditText_isOnlyInputEmail, false);
        isOnlyInputPhone = arrays.getBoolean(R.styleable.CEditText_isOnlyInputPhone, false);
        isOnlyInputIdCard = arrays.getBoolean(R.styleable.CEditText_isOnlyInputIdCard, false);
        isOnlyInputChinesed = arrays.getBoolean(R.styleable.CEditText_isOnlyInputChinesed, false); //中文加点
        isOnlyInputChEnNum = arrays.getBoolean(R.styleable.CEditText_isOnlyInputChEnNum, false); //中文英文加数字
        maxNumberSize = arrays.getInt(R.styleable.CEditText_maxNumberSize, 0);
        maxDecimalSize = arrays.getInt(R.styleable.CEditText_maxDecimalSize, 0);
        maxInputSize = arrays.getInt(R.styleable.CEditText_maxInputSize, 0);
        canInputSpace = arrays.getBoolean(R.styleable.CEditText_canInputSpace, false);
        canInputEnter = arrays.getBoolean(R.styleable.CEditText_canInputEnter, false);
        canInputEmoji = arrays.getBoolean(R.styleable.CEditText_canInputEmoji, false);
        inputFilters = new ArrayList<>();
        if (isOnlyInputNumber) { //只能输入数字
            setInputType(InputType.TYPE_CLASS_NUMBER);
            if (maxInputSize > 0) {//限制长度
                inputFilters.add(new InputFilter.LengthFilter(maxInputSize));
            }
        } else if (isOnlyInputDecimal) {//只能输入小数
            setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
            if (maxInputSize > 0) { //限制长度
                inputFilters.add(new InputFilter.LengthFilter(maxInputSize));
            }
        } else if (isOnlyInputChinese) {//只能输入中文
            inputFilters.add(new RegexResultFilter(CHINE_SWORD));
            if (maxInputSize > 0) { //限制长度
                inputFilters.add(new InputFilter.LengthFilter(maxInputSize));
            }
        } else if (isOnlyInputNumEn) { //英文和数字
            inputFilters.add(new RegexResultFilter(EN_NUMBER));
            if (maxInputSize > 0) { //限制长度
                inputFilters.add(new InputFilter.LengthFilter(maxInputSize));
            }
        } else if (isOnlyInputEmail) { //邮箱验证
            inputFilters.add(new RegexResultFilter(EMAIL_REGEX));
        } else if (isOnlyInputPhone) { //1[3456789]开始的手机号码
            inputFilters.add(new RegexResultFilter(PHONE_REGEX));
        } else if (isOnlyInputIdCard) { //身份证号码
            inputFilters.add(new RegexResultFilter(ID_CARD_REG));
        } else if (isOnlyInputChinesed) { //中文和·
            inputFilters.add(new RegexResultFilter(REGEX_CHINESE_NAME));
            if (maxInputSize > 0) { //限制长度
                inputFilters.add(new InputFilter.LengthFilter(maxInputSize));
            }
        } else if (isOnlyInputChEnNum) { //中文英文和数字
            inputFilters.add(new RegexResultFilter(REGEX_ZH_NB_EN));
            if (maxInputSize > 0) { //限制长度
                inputFilters.add(new InputFilter.LengthFilter(maxInputSize));
            }
        } else if (maxNumberSize > 0 && maxDecimalSize > 0) {
            String regex = DEFAULT_MAX_MONEY_VALUE;
            regex = regex.replaceAll(\"numSize\", maxNumberSize + \"\").replaceAll(\"maxDecimalSize\", maxDecimalSize + \"\");
            //限制整数部分或者小数部分的长度
            inputFilters.add(new RegexResultFilter(regex));
        } else if (maxNumberSize > 0 && maxDecimalSize <= 0) {
            String regex = DEFAULT_LIMIT_NUM;
            regex = regex.replaceAll(\"numSize\", maxNumberSize + \"\");
            inputFilters.add(new RegexResultFilter(regex)); //限制整数部分或者小数部分的长度
        } else if (maxNumberSize <= 0 && maxDecimalSize > 0) {
            String regex = DEFAULT_LIMIT_DECIMAL;
            regex = regex.replaceAll(\"maxDecimalSize\", maxDecimalSize + \"\");
            inputFilters.add(new RegexResultFilter(regex)); //限制整数部分或者小数部分的长度
        }
        setCanInputSpaceEnterEmoji(inputFilters);
        setDefaultFilers(inputFilters);
    }

    /**
     * 是否可以输入表情,空格,回车
     *
     * @param inputFilters
     */
    private void setCanInputSpaceEnterEmoji(List<InputFilter> inputFilters) {
        if (!canInputEmoji) {
            inputFilters.add(new InputFilterEmoji());
        }
        if (!canInputEnter) {
            inputFilters.add(new RegexInputFilter(ENTER_REGEX, false));
        }
        if (!canInputSpace) {
            inputFilters.add(new RegexInputFilter(SPACE_REGEX, false));
        }
    }


    private void setDefaultFilers(List<InputFilter> inputFilters) {
        if (inputFilters == null || inputFilters.isEmpty()) {
            return;
        }
        InputFilter[] newFilters = new InputFilter[inputFilters.size()];
        for (int i = 0; i < inputFilters.size(); i++) {
            newFilters[i] = inputFilters.get(i);
        }
        setFilters(newFilters);

    }

    //设置用户自己需要的filter
    public void setMyFilers(List<InputFilter> filters, boolean isUseDefaultFilter) {
        if (isUseDefaultFilter && inputFilters != null) {
            inputFilters.addAll(filters);
            setDefaultFilers(inputFilters);
        } else {
            setDefaultFilers(filters);
        }

    }

    public class RegexResultFilter implements InputFilter {
        private static final String POINTER = \".\";

        private static final String ZERO = \"0\";
        final private Pattern enterPattern;

        /**
         * @param regex 内容正则表达式
         *              如果内容和正则表达式匹配,如果是想匹配留下的内容,则显示到输入框,否则不显示到输入框
         *              如果内容和正则表达式不匹配,正好与上面相反
         */
        public RegexResultFilter(String regex) {
            enterPattern = Pattern.compile(regex);
        }

        /**
         * @param source 输入的文字
         * @param start  输入-0,删除-0
         * @param end    输入-文字的长度,删除-0
         * @param dest   原先显示的内容
         * @param dstart 输入-原光标位置,删除-光标删除结束位置
         * @param dend   输入-原光标位置,删除-光标删除开始位置
         * @return
         */
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            String destText = dest.toString();
            if (enterPattern != null) {
                StringBuilder stringBuilder = new StringBuilder();
                if (end > 0) {
                    //TODO 输入 - 开始部分
                    stringBuilder.append(dest.subSequence(0, dstart));
                    //TODO 输入 - 键盘输入
                    stringBuilder.append(source);
                    //TODO 输入 - 结束部分
                    stringBuilder.append(dest.subSequence(dstart, dest.length()));
                } else {
                    //TODO 删除 - 开始部分
                    stringBuilder.append(dest.subSequence(0, dstart));
                    //TODO 删除 - 结束部分
                    stringBuilder.append(dest.subSequence(dend, dest.length()));
                }

                final String result = stringBuilder.toString();
                System.out.println(\"预计结果: \" + stringBuilder.toString());

                //TODO 如果正则满足,返回输入内容
                //TODO 如果不满足正则但是接受内容,返回输入内容
                if (!POINTER.equals(source.toString()) && ZERO.equals(destText)) { //如果首位输入0,接下来只能输入小数点
                    return \"\";
                } else if (match(source, start, end, result)) {
                    return source;
                } else {
                    return \"\";
                }
            } else {
                return source;
            }
        }

        //TODO 匹配正则
        protected boolean match(CharSequence source, int start, int end, String result) {
            return enterPattern.matcher(result).matches();
        }

    }

    public class InputFilterEmoji implements InputFilter {
        Pattern emoji = Pattern.compile(\"[\\ud83c\\udc00-\\ud83c\\udfff]|[\\ud83d\\udc00-\\ud83d\\udfff]|[\\u2600-\\u27ff]\",
                Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);

        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            Matcher emojiMatcher = emoji.matcher(source);
            if (emojiMatcher.find()) {
                return \"\";
            }
            return null;
        }
    }

    public class RegexInputFilter implements InputFilter {

        Pattern enterPattern = null;
        boolean mExpectMatch = true;

        /**
         * @param regex       内容正则表达式
         * @param expectMatch true 期望匹配, false 期望不匹配
         *                    如果内容和正则表达式匹配,如果是想匹配留下的内容,则显示到输入框,否则不显示到输入框
         *                    如果内容和正则表达式不匹配,正好与上面相反
         */
        public RegexInputFilter(String regex, boolean expectMatch) {
            enterPattern = Pattern.compile(regex);
            this.mExpectMatch = expectMatch;
        }

        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            if (enterPattern != null) {
                if (enterPattern.matcher(source).matches()) {
                    if (mExpectMatch) {
                        return source;
                    } else {
                        return \"\";
                    }
                } else {
                    if (mExpectMatch) {
                        return \"\";
                    } else {
                        return source;
                    }
                }
            } else {
                return source;
            }
        }
    }


}

 

attrs.

增加:

<declare-styleable name=\"CEditText\">
    <attr name=\"isOnlyInputNumber\" format=\"boolean\"/>
    <attr name=\"isOnlyInputDecimal\" format=\"boolean\"/>
    <attr name=\"isOnlyInputChinese\" format=\"boolean\"/>
    <attr name=\"isOnlyInputChinesed\" format=\"boolean\"/>
    <attr name=\"isOnlyInputNumEn\" format=\"boolean\"/>
    <attr name=\"isOnlyInputEmail\" format=\"boolean\"/>
    <attr name=\"isOnlyInputPhone\" format=\"boolean\"/>
    <attr name=\"isOnlyInputIdCard\" format=\"boolean\"/>
    <attr name=\"isOnlyInputChEnNum\" format=\"boolean\"/>
    <attr name=\"maxNumberSize\" format=\"integer\"/>
    <attr name=\"maxDecimalSize\" format=\"integer\"/>
    <attr name=\"maxInputSize\" format=\"integer\"/>
    <attr name=\"canInputSpace\" format=\"boolean\"/>
    <attr name=\"canInputEnter\" format=\"boolean\"/>
    <attr name=\"canInputEmoji\" format=\"boolean\"/>
</declare-styleable>

 

使用:包名注意替换

<com.fkhwl.common.widget.CEditText
    android:id=\"@+id/troubleContent\"
    android:layout_width=\"match_parent\"
    android:layout_height=\"200dp\"
    android:layout_marginBottom=\"10dp\"
    android:layout_marginLeft=\"5dp\"
    android:layout_marginRight=\"10dp\"
    android:layout_marginTop=\"10dp\"
    android:background=\"@drawable/edittext_gray_white_bg\"
    android:gravity=\"top|left\"
    android:paddingLeft=\"1dp\"
    app:isOnlyInputPhone=\"true\"  //只能输入手机号码
     />

 

收藏 打印