InputFilter实现EditText过滤中文字符、空格等特殊字符
来源:互联网 发布:淘宝网店详情页制作 编辑:程序博客网 时间:2024/05/22 10:15
最近项目要求EditText输入文字时过滤掉中文字符、空格等特殊字符,上网查了好多资料,最后决定使用IputFilter来实现这一功能,写一篇博客来记录一下自己的心得
先上效果图
主要代码
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行不进行过滤
- InputFilter实现EditText过滤中文字符、空格等特殊字符
- EditText 输入控制,用InputFilter过滤表情、特殊字符
- EditText中文过滤,InputFilter
- EditText利用InputFilter过滤特殊字符或改变输入的内容
- Android EditText 使用InputFilter区分中文英文字符长度
- Android EditText实现字符过滤
- Android EditText实现字符过滤
- edittext 特殊字符过滤和字符长度限制
- Android EditText 特殊字符过滤和字符输入长度限制
- php过滤斜杠等特殊字符
- 关于Android HTTP请求URI中包含特殊字符,例如中文,空格等,请求400
- Android EditText禁止输入空格和特殊字符
- EditText禁止输入空格、换行符或特殊字符
- SQL过滤掉空格和其他特殊字符函数
- SQL过滤掉空格和其他特殊字符函数
- 限制表单输入框过滤特殊字符及空格
- PHP 正则表达式过滤特殊字符和空格
- 字符数组过滤特殊字符
- Oracle 序列 sequence
- 分布式管理控制系统Git与项目托管平台Github相关概念、工作流程与操作方法
- Quartz详解之quartz基本概念
- ffmpeg视频添加filter-flv
- 正则表达试
- InputFilter实现EditText过滤中文字符、空格等特殊字符
- Netty 4.0 实现心跳检测和断线重连
- 点击图片让video视频显示并自动播放/循环播放
- SpringMVC注解说明
- 阿里开源全局图
- 性能调优之MYSQL高并发优化
- Install SharePoint 2013 with SP1 on Windows Server 2012 R2 error - This Product requires .NF 4.5
- 面试难度:2个数的互换
- • Spring Boot 进 阶- 框架搭建