e4721a1a3b911acf589511d95f082539839a5792.svn-base 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. package com.hjq.widget;
  2. import android.content.Context;
  3. import android.content.res.TypedArray;
  4. import android.support.v7.widget.AppCompatEditText;
  5. import android.text.InputFilter;
  6. import android.text.Spanned;
  7. import android.util.AttributeSet;
  8. import java.util.regex.Pattern;
  9. /**
  10. * Created by Android Studio.
  11. * User: zbb
  12. * Date: 2020/1/2
  13. * Describe: RegexEditText
  14. */
  15. public class RegexEditText extends AppCompatEditText implements InputFilter {
  16. /** 手机号(只能以 1 开头) */
  17. public static final String REGEX_MOBILE = "[1]\\d{0,10}";
  18. /** 中文(普通的中文字符) */
  19. public static final String REGEX_CHINESE = "[\\u4e00-\\u9fa5]*";
  20. /** 英文(大写和小写的英文) */
  21. public static final String REGEX_ENGLISH = "[a-zA-Z]*";
  22. /** 计数(非 0 开头的数字) */
  23. public static final String REGEX_COUNT = "[1-9]\\d*";
  24. /** 用户名(中文、英文、数字) */
  25. public static final String REGEX_NAME = "[" + REGEX_CHINESE + "|" + REGEX_ENGLISH + "|" + "\\d*" + "]*";
  26. /** 非空格的字符(不能输入空格) */
  27. public static final String REGEX_NONNULL = "\\S+";
  28. /** 正则表达式规则 */
  29. private Pattern mPattern;
  30. public RegexEditText(Context context) {
  31. super(context);
  32. initialize(context, null);
  33. }
  34. public RegexEditText(Context context, AttributeSet attrs) {
  35. super(context, attrs);
  36. initialize(context, attrs);
  37. }
  38. public RegexEditText(Context context, AttributeSet attrs, int defStyleAttr) {
  39. super(context, attrs, defStyleAttr);
  40. initialize(context, attrs);
  41. }
  42. /**
  43. * 初始化属性
  44. */
  45. protected void initialize(Context context, AttributeSet attrs) {
  46. final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RegexEditText);
  47. if (array.hasValue(R.styleable.RegexEditText_inputRegex)) {
  48. setInputRegex(array.getString(R.styleable.RegexEditText_inputRegex));
  49. } else {
  50. if (array.hasValue(R.styleable.RegexEditText_regexType)) {
  51. int regexType = array.getInt(R.styleable.RegexEditText_regexType, 0);
  52. switch (regexType) {
  53. case 0x01:
  54. setInputRegex(REGEX_MOBILE);
  55. break;
  56. case 0x02:
  57. setInputRegex(REGEX_CHINESE);
  58. break;
  59. case 0x03:
  60. setInputRegex(REGEX_ENGLISH);
  61. break;
  62. case 0x04:
  63. setInputRegex(REGEX_COUNT);
  64. break;
  65. case 0x05:
  66. setInputRegex(REGEX_NAME);
  67. break;
  68. case 0x06:
  69. setInputRegex(REGEX_NONNULL);
  70. break;
  71. default:
  72. break;
  73. }
  74. }
  75. }
  76. array.recycle();
  77. }
  78. /**
  79. * 是否有这个输入标记
  80. */
  81. public boolean hasInputType(int type) {
  82. return (getInputType() & type) != 0;
  83. }
  84. /**
  85. * 添加一个输入标记
  86. */
  87. public void addInputType(int type) {
  88. setInputType(getInputType() | type);
  89. }
  90. /**
  91. * 移除一个输入标记
  92. */
  93. public void removeInputType(int type) {
  94. setInputType(getInputType() & ~type);
  95. }
  96. /**
  97. * 设置输入正则
  98. */
  99. public void setInputRegex(String regex) {
  100. if (regex == null || "".equals(regex)) {
  101. return;
  102. }
  103. mPattern = Pattern.compile(regex);
  104. addFilters(this);
  105. }
  106. /**
  107. * 获取输入正则
  108. */
  109. public String getInputRegex() {
  110. if (mPattern == null) {
  111. return null;
  112. }
  113. return mPattern.pattern();
  114. }
  115. /**
  116. * 添加筛选规则
  117. */
  118. public void addFilters(InputFilter filter) {
  119. if (filter == null) {
  120. return;
  121. }
  122. final InputFilter[] newFilters;
  123. final InputFilter[] oldFilters = getFilters();
  124. if (oldFilters != null && oldFilters.length > 0) {
  125. newFilters = new InputFilter[oldFilters.length + 1];
  126. // 复制旧数组的元素到新数组中
  127. System.arraycopy(oldFilters, 0, newFilters, 0, oldFilters.length);
  128. newFilters[oldFilters.length] = filter;
  129. } else {
  130. newFilters = new InputFilter[1];
  131. newFilters[0] = filter;
  132. }
  133. super.setFilters(newFilters);
  134. }
  135. /**
  136. * {@link InputFilter}
  137. *
  138. * @param source 新输入的字符串
  139. * @param start 新输入的字符串起始下标,一般为0
  140. * @param end 新输入的字符串终点下标,一般为source长度-1
  141. * @param dest 输入之前文本框内容
  142. * @param dstart 原内容起始坐标,一般为0
  143. * @param dend 原内容终点坐标,一般为dest长度-1
  144. * @return 返回字符串将会加入到内容中
  145. */
  146. @Override
  147. public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
  148. if (mPattern == null) {
  149. return source;
  150. }
  151. // 拼接出最终的字符串
  152. String begin = dest.toString().substring(0, dstart);
  153. String over = dest.toString().substring(dstart + (dend - dstart), dstart + (dest.toString().length() - begin.length()));
  154. String result = begin + source + over;
  155. // 判断是插入还是删除
  156. if (dstart > dend - 1) {
  157. if (mPattern.matcher(result).matches()) {
  158. // 如果匹配就允许这个文本通过
  159. return source;
  160. }
  161. } else {
  162. if (!mPattern.matcher(result).matches()) {
  163. // 如果不匹配则不让删除(删空操作除外)
  164. if (!"".equals(result)) {
  165. return dest.toString().substring(dstart, dend);
  166. }
  167. }
  168. }
  169. // 注意这里不能返回 null,否则会和 return source 效果一致
  170. return "";
  171. }
  172. }