InputFilter实现EditText过滤中文字符、空格等特殊字符
2017-01-23 17:47
393 查看
最近项目要求EditText输入文字时过滤掉中文字符、空格等特殊字符,上网查了好多资料,最后决定使用IputFilter来实现这一功能,写一篇博客来记录一下自己的心得
先上效果图
![](http://img.blog.csdn.net/20170309111713543?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjU2NTI5MDc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
主要代码
自定义属性文件在attrs.xml文件中
XML布局中的使用方式
代码分析
上述代码8-11,14-18分别是自定义EditText构造函数当中都有一个初始化init(attrs)方法,我们在此方法中实现自定义属性的解析,和自定义InputFilter过滤器的实现
![](http://img.blog.csdn.net/20170123181107976?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjU2NTI5MDc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
20行代码,可能到家会对自定义属性maxLength感到疑惑,因为EditText有一个属性android:maxLength=”19”为什么这里还要设置一个自定义属性,岂不是多此一举,我子啊这里要解释一下android:maxLength=”19”这个属性是在EditText的父类也就是TextView中使用到的,我们进入到TextView的代码中我们看一看
![](http://img.blog.csdn.net/20170123181757015?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
这行代码实在TextView的构造函数中,其中maxLength就是解析TextView属性android:maxLength的到的值,我们在这里可以看到此处会根据maxLength的长度来用不同的策略来设置InputFilters这个数组,最后在通过setFilters()这个方法去设置TextView的过滤器,我们看到maxLength长度大于0时,会给InputFilter[]数组设置一个成员new InputFilter.LengthFilter(maxlength) TextView和EidtText正是由于设置了这样一个InputFilter才实现文字长度的限制
![](http://img.blog.csdn.net/20170123183149332?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjU2NTI5MDc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
进入到LengthFilter的源码中我们发现LengthFilter 实现了 InputFilter这个接口并实现了filter()这个方法,因此才能实现对TextView、EditText的字符长度的限制。我门今天实现的就是通过自定InputFilter实现EditText过滤中文、空格等特殊字符,而这其中的关键也是在于实现InputFilter接口通过实现filter()这个方法,来达到实现字符的过滤
我们还是从最关键的地方Init函数分析
6行判断maxLength 属性是否大于0(默认为0,大于0说明在布局xml中view的属性中设置过),接下来第7行setFilters(new InputFilter[])我们看到该方法的参数是一个InputFilter[]数组,实际上就是说可以通过多组合InputFilter来实现各种过滤的效果,我们实现的就是过滤中文字符和空字符串,所以我在数组的第二个变量中重写InputFilter的filter方法来实现这样的效果。filter过滤是通过返回值来决定的
return “”
表示过滤输入的内容
return null
表示不过滤输入的内容
我们看10行先判断是不允许输入空字符串,进入11行判断输入内容是为空字符串过滤,15行判断不允许输入中文进入16行判断输入内容为中文字符过滤,否则进入20行不进行过滤
先上效果图
主要代码
public class NoMenuEditText extends EditText { private final Context context; private int maxLength;//自定义属性判断是输入字符的最大长度 private boolean allow_blank;//自定义属性判断是否允许输入空格,默认false private boolean allow_chinese;//自定义属性判断是否允许输入中文 public NoMenuEditText(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; init(attrs); } public NoMenuEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; init(attrs); } private void init(AttributeSet attrs) { final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NoMenuEditText);//加载自定义styleable文件 maxLength = a.getInteger(R.styleable.NoMenuEditText_maxLength,0);//读取自定义属性输入字符的最大长度 allow_blank = a.getBoolean(R.styleable.NoMenuEditText_allow_blank, false);//读取自定义属性是否允许输入空格 allow_chinese = a.getBoolean(R.styleable.NoMenuEditText_allow_chinese,false);//读取自定义属性是否允许输入中文 if (maxLength > 0){ setFilters(new InputFilter[]{new LengthFilter(maxLength),new InputFilter() { @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { if (!allow_blank){ if (source.equals(" ")) { return ""; } } if (!allow_chinese){ if (checkNameChese(source.toString())){ return ""; } } return null; } }}); }else { setFilters(new InputFilter[]{new InputFilter() { @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { if (!allow_blank){ if (source.equals(" ")) { return ""; } } if (!allow_chinese){ if (checkNameChese(source.toString())){ return ""; } } return null; } }}); } this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor()); this.setLongClickable(false); } private class ActionModeCallbackInterceptor implements ActionMode.Callback { private final String TAG = NoMenuEditText.class.getSimpleName(); @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; } @Override public void onDestroyActionMode(ActionMode mode) { } } public boolean stringFilter(String str){ // 只允许字母、数字和汉字 String regEx = "[^\u4E00-\u9FA5]"; Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(str); return m.matches(); } /** * 判定输入汉字 * @param c * @return */ public boolean isChinese(char c) { Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { return true; } return false; } /** * 检测String是否全是中文 * @param name * @return */ public boolean checkNameChese(String name) { boolean res=false; char [] cTemp = name.toCharArray(); for(int i=0;i<name.length();i++) { if(isChinese(cTemp[i])) { res=true; break; } } return res; } }
自定义属性文件在attrs.xml文件中
<declare-styleable name="NoMenuEditText"> <attr name="allow_blank" format="boolean" /> <attr name="maxLength" format="integer" /> <attr name="allow_chinese" format="boolean" /> </declare-styleable>
XML布局中的使用方式
<com.xfzd.client.user.view.NoMenuEditText xmlns:aa="http://schemas.android.com/apk/res-auto/com.xfzd.client" aa:allow_blank="true" aa:maxLength="20"
代码分析
上述代码8-11,14-18分别是自定义EditText构造函数当中都有一个初始化init(attrs)方法,我们在此方法中实现自定义属性的解析,和自定义InputFilter过滤器的实现
20行代码,可能到家会对自定义属性maxLength感到疑惑,因为EditText有一个属性android:maxLength=”19”为什么这里还要设置一个自定义属性,岂不是多此一举,我子啊这里要解释一下android:maxLength=”19”这个属性是在EditText的父类也就是TextView中使用到的,我们进入到TextView的代码中我们看一看
这行代码实在TextView的构造函数中,其中maxLength就是解析TextView属性android:maxLength的到的值,我们在这里可以看到此处会根据maxLength的长度来用不同的策略来设置InputFilters这个数组,最后在通过setFilters()这个方法去设置TextView的过滤器,我们看到maxLength长度大于0时,会给InputFilter[]数组设置一个成员new InputFilter.LengthFilter(maxlength) TextView和EidtText正是由于设置了这样一个InputFilter才实现文字长度的限制
进入到LengthFilter的源码中我们发现LengthFilter 实现了 InputFilter这个接口并实现了filter()这个方法,因此才能实现对TextView、EditText的字符长度的限制。我门今天实现的就是通过自定InputFilter实现EditText过滤中文、空格等特殊字符,而这其中的关键也是在于实现InputFilter接口通过实现filter()这个方法,来达到实现字符的过滤
我们还是从最关键的地方Init函数分析
private void init(AttributeSet attrs) { final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NoMenuEditText);//加载自定义styleable文件 maxLength = a.getInteger(R.styleable.NoMenuEditText_maxLength,0);//读取自定义属性输入字符的最大长度 allow_blank = a.getBoolean(R.styleable.NoMenuEditText_allow_blank, false);//读取自定义属性是否允许输入空格 allow_chinese = a.getBoolean(R.styleable.NoMenuEditText_allow_chinese,false);//读取自定义属性是否允许输入中文 if (maxLength > 0){ setFilters(new InputFilter[]{new LengthFilter(maxLength),new InputFilter() { @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { if (!allow_blank){ if (source.equals(" ")) { return ""; } } if (!allow_chinese){ if (checkNameChese(source.toString())){ return ""; } } return null; } }}); }else { setFilters(new InputFilter[]{new InputFilter() { @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { if (!allow_blank){ if (source.equals(" ")) { return ""; } } if (!allow_chinese){ if (checkNameChese(source.toString())){ return ""; } } return null; } }}); } this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor()); this.setLongClickable(false); }
6行判断maxLength 属性是否大于0(默认为0,大于0说明在布局xml中view的属性中设置过),接下来第7行setFilters(new InputFilter[])我们看到该方法的参数是一个InputFilter[]数组,实际上就是说可以通过多组合InputFilter来实现各种过滤的效果,我们实现的就是过滤中文字符和空字符串,所以我在数组的第二个变量中重写InputFilter的filter方法来实现这样的效果。filter过滤是通过返回值来决定的
return “”
表示过滤输入的内容
return null
表示不过滤输入的内容
我们看10行先判断是不允许输入空字符串,进入11行判断输入内容是为空字符串过滤,15行判断不允许输入中文进入16行判断输入内容为中文字符过滤,否则进入20行不进行过滤
相关文章推荐
- asp.net怎样在URL中使用中文、空格、特殊字符
- asp.net怎样在URL中使用中文、空格、特殊字符
- Android EditText 特殊字符过滤和字符输入长度限制
- 统计一段文字中数组、中文、英文字母、空格以及其他特殊字符出现的次数
- 练习JavaScript实现过滤特殊字符
- asp.net怎样在URL中使用中文、空格、特殊字符
- JS过滤url参数特殊字符的实现方法
- python 实现 urlencode 与 urldecode (中文及特殊字符编解码)
- 关于 android 中 edittext 特殊字符过滤和字符长度限制的最优方法
- C#实现过滤sql特殊字符的方法集合
- asp.net怎样在URL中使用中文、空格、特殊字符
- js中用正则表达式 过滤特殊字符, js验证中文字母数字
- 关于 android 中 edittext 特殊字符过滤和字符长度限制的最优方法
- android中edittext特殊字符过滤和字符长度限制的最优方法
- asp.net怎样在URL中使用中文、空格、特殊字符
- 关于 android 中 edittext 特殊字符过滤和字符长度限制的最优方法
- 关于android中edittext特殊字符过滤和字符长度限制的最优方法
- 关于 android 中 edittext 特殊字符过滤和字符长度限制的最优方法
- PHP实现过滤掉非汉字字符只保留中文字符
- 关于在 Android EditText 控件 中过滤空格或其他字符