| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- package com.hjq.widget;
- import android.content.Context;
- import android.content.res.TypedArray;
- import android.support.v7.widget.AppCompatEditText;
- import android.text.InputFilter;
- import android.text.Spanned;
- import android.util.AttributeSet;
- import java.util.regex.Pattern;
- /**
- * Created by Android Studio.
- * User: zbb
- * Date: 2020/1/2
- * Describe: RegexEditText
- */
- public class RegexEditText extends AppCompatEditText implements InputFilter {
- /** 手机号(只能以 1 开头) */
- public static final String REGEX_MOBILE = "[1]\\d{0,10}";
- /** 中文(普通的中文字符) */
- public static final String REGEX_CHINESE = "[\\u4e00-\\u9fa5]*";
- /** 英文(大写和小写的英文) */
- public static final String REGEX_ENGLISH = "[a-zA-Z]*";
- /** 计数(非 0 开头的数字) */
- public static final String REGEX_COUNT = "[1-9]\\d*";
- /** 用户名(中文、英文、数字) */
- public static final String REGEX_NAME = "[" + REGEX_CHINESE + "|" + REGEX_ENGLISH + "|" + "\\d*" + "]*";
- /** 非空格的字符(不能输入空格) */
- public static final String REGEX_NONNULL = "\\S+";
- /** 正则表达式规则 */
- private Pattern mPattern;
- public RegexEditText(Context context) {
- super(context);
- initialize(context, null);
- }
- public RegexEditText(Context context, AttributeSet attrs) {
- super(context, attrs);
- initialize(context, attrs);
- }
- public RegexEditText(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- initialize(context, attrs);
- }
- /**
- * 初始化属性
- */
- protected void initialize(Context context, AttributeSet attrs) {
- final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RegexEditText);
- if (array.hasValue(R.styleable.RegexEditText_inputRegex)) {
- setInputRegex(array.getString(R.styleable.RegexEditText_inputRegex));
- } else {
- if (array.hasValue(R.styleable.RegexEditText_regexType)) {
- int regexType = array.getInt(R.styleable.RegexEditText_regexType, 0);
- switch (regexType) {
- case 0x01:
- setInputRegex(REGEX_MOBILE);
- break;
- case 0x02:
- setInputRegex(REGEX_CHINESE);
- break;
- case 0x03:
- setInputRegex(REGEX_ENGLISH);
- break;
- case 0x04:
- setInputRegex(REGEX_COUNT);
- break;
- case 0x05:
- setInputRegex(REGEX_NAME);
- break;
- case 0x06:
- setInputRegex(REGEX_NONNULL);
- break;
- default:
- break;
- }
- }
- }
- array.recycle();
- }
- /**
- * 是否有这个输入标记
- */
- public boolean hasInputType(int type) {
- return (getInputType() & type) != 0;
- }
- /**
- * 添加一个输入标记
- */
- public void addInputType(int type) {
- setInputType(getInputType() | type);
- }
- /**
- * 移除一个输入标记
- */
- public void removeInputType(int type) {
- setInputType(getInputType() & ~type);
- }
- /**
- * 设置输入正则
- */
- public void setInputRegex(String regex) {
- if (regex == null || "".equals(regex)) {
- return;
- }
- mPattern = Pattern.compile(regex);
- addFilters(this);
- }
- /**
- * 获取输入正则
- */
- public String getInputRegex() {
- if (mPattern == null) {
- return null;
- }
- return mPattern.pattern();
- }
- /**
- * 添加筛选规则
- */
- public void addFilters(InputFilter filter) {
- if (filter == null) {
- return;
- }
- final InputFilter[] newFilters;
- final InputFilter[] oldFilters = getFilters();
- if (oldFilters != null && oldFilters.length > 0) {
- newFilters = new InputFilter[oldFilters.length + 1];
- // 复制旧数组的元素到新数组中
- System.arraycopy(oldFilters, 0, newFilters, 0, oldFilters.length);
- newFilters[oldFilters.length] = filter;
- } else {
- newFilters = new InputFilter[1];
- newFilters[0] = filter;
- }
- super.setFilters(newFilters);
- }
- /**
- * {@link InputFilter}
- *
- * @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) {
- if (mPattern == null) {
- return source;
- }
- // 拼接出最终的字符串
- String begin = dest.toString().substring(0, dstart);
- String over = dest.toString().substring(dstart + (dend - dstart), dstart + (dest.toString().length() - begin.length()));
- String result = begin + source + over;
- // 判断是插入还是删除
- if (dstart > dend - 1) {
- if (mPattern.matcher(result).matches()) {
- // 如果匹配就允许这个文本通过
- return source;
- }
- } else {
- if (!mPattern.matcher(result).matches()) {
- // 如果不匹配则不让删除(删空操作除外)
- if (!"".equals(result)) {
- return dest.toString().substring(dstart, dend);
- }
- }
- }
- // 注意这里不能返回 null,否则会和 return source 效果一致
- return "";
- }
- }
|