1. 项目需求:

输入框限制输入内容为英文字符,数字,中文;长度限制最多6个字符

2. 需求拆分:

1> 字符类型限制
2> 字符长度限制

3. 方案实施:

1> 字符类型通过正则表达式进行过滤

        //类型过滤器InputFilter typeFilter = new InputFilter() {@Overridepublic CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {//1. 数字,英文字符,中文字符正则表达式Pattern p = Pattern.compile("[0-9a-zA-Z|\u4e00-\u9fa5]+");Matcher m = p.matcher(source.toString());//2. 未匹配到的字符,返回""进行过滤if (!m.matches()) return "";return null;}};//将过滤器添加至EditText中editText.setFilters(new InputFilter[]{typeFilter});

2> 字符长度直接通过TextWatcher回调中的afterTextChanged判断过滤

        editText.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}@Overridepublic void afterTextChanged(Editable s) {Log.v(TAG, "afterTextChanged() called with: s = [" + s.toString() + "]");//1. 判断输入字符长度if(s.toString().length() > STR_LENGTH_LIMIT) {//2. 若长度大于限制,则截取限制长度editText.setText(s.toString().substring(0,STR_LENGTH_LIMIT));//3. 将光标移至末尾位置editText.setSelection(editText.getText().length());}}});

4. 方案问题

当输入中文时,由于输入框中会先键入拼音字母的选中值,此时也会触发afterTextChanged回调,导致拼音还未输入完成但已达到最大字符限制后,直接会被打断,eg:字符限制长度为6,当输入“我叫小明”,相应键入的拼音为“wojiaoxiaoming”,当输入到“wojiao”后,后面输入的内容就会打断拼音输入,直接键入所输入的字符;因为afterTextChanged中已经已经获取到了“wojiao”长度为6,后面再输入时导致字符直接被截断

拼音输入中文时,回调打印

2021-12-10 14:29:44.627 4497-4497/com.boom.inputmethodtest V/EditTextDemo: afterTextChanged() called with: s = []
2021-12-10 14:29:46.846 4497-4497/com.boom.inputmethodtest V/EditTextDemo: afterTextChanged() called with: s = [w]
2021-12-10 14:29:47.081 4497-4497/com.boom.inputmethodtest V/EditTextDemo: afterTextChanged() called with: s = [wo]
2021-12-10 14:29:47.348 4497-4497/com.boom.inputmethodtest V/EditTextDemo: afterTextChanged() called with: s = [woj]
2021-12-10 14:29:47.591 4497-4497/com.boom.inputmethodtest V/EditTextDemo: afterTextChanged() called with: s = [woji]
2021-12-10 14:29:47.733 4497-4497/com.boom.inputmethodtest V/EditTextDemo: afterTextChanged() called with: s = [wojia]
2021-12-10 14:29:47.968 4497-4497/com.boom.inputmethodtest V/EditTextDemo: afterTextChanged() called with: s = [wojiao]
//该次输入后字符便被截断
2021-12-10 14:29:49.511 4497-4497/com.boom.inputmethodtest V/EditTextDemo: afterTextChanged() called with: s = [wojiaox]
2021-12-10 14:29:49.530 4497-4497/com.boom.inputmethodtest V/EditTextDemo: afterTextChanged() called with: s = [wojiao]

5. 解决思路

1> 对于此问题,要解决的就是如何在通过拼音输入中文时,使拼音的待输入字符做到去除afterTextChanged的回调,通过3.1>中对非需求字符的过滤,得到启发,是否可以寻找一种特殊规则将拼音输入的字符进行过滤从而达到去除afterTextChanged回调的效果
2> 根据第一点的思路,先找出拼音输入时的特征,发现拼音输入时字符的体现形式预纯英文字符/数字有所区别,拼音键入时的字符会有下划线标识(不同输入法可能表现不一致),那就可以通过此标识来实现一个标识过滤器
3> 对于这种下划线效果,基本都是通过Spannable来进行实现的,因此我们可以通过判断字符的Span类型达到过滤效果

        InputFilter spanFilter = new InputFilter() {@Overridepublic CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {Log.d(TAG, "filter() called with: source = [" + source + " , " + source.getClass().getSimpleName() + "], start = [" + start + "], end = [" + end + "], dest = [" + dest + "], dstart = [" + dstart + "], dend = [" + dend + "]");SpannableString ss = new SpannableString(source);Object[] spanArray = ss.getSpans(0,ss.length() , Object.class);if(spanArray != null) {for (int i = 0; i < spanArray.length; i++) {if(spanArray[i] instanceof UnderlineSpan) {return "";}}}return null;}};

如上我们通过判断字符Span类型,若查到某个字符以目标Span类型出现(此处为UnderlineSpan即下划线效果,其他场景需要根据各自输入法的效果进行适配,有的输入法为BackgroundColorSpan即背景色效果)则进行过滤;此时输入框内便不会显示待输入的字符串,也即不会有afterTextChanged回调。
当然这里也会引入一个体验性问题,用户无法看到他所键入的内容,只有输入法的联想词栏会有对应的内容显示,选中后便会键入输入框。

ps:通过日志打印,也可以看到此处的CharSequence实例类为SpannableStringBuilder

2021-12-10 15:24:48.706 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [w , SpannableStringBuilder], start = [0], end = [1], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:48.865 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [wo , SpannableStringBuilder], start = [0], end = [2], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:49.617 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [wos , SpannableStringBuilder], start = [0], end = [3], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:49.904 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [wosh , SpannableStringBuilder], start = [0], end = [4], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:50.122 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [woshi , SpannableStringBuilder], start = [0], end = [5], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:50.458 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [woshix , SpannableStringBuilder], start = [0], end = [6], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:50.643 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [woshixi , SpannableStringBuilder], start = [0], end = [7], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:50.794 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [woshixia , SpannableStringBuilder], start = [0], end = [8], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:50.944 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [woshixiao , SpannableStringBuilder], start = [0], end = [9], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:51.398 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [woshixiaom , SpannableStringBuilder], start = [0], end = [10], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:52.774 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [woshixiaomi , SpannableStringBuilder], start = [0], end = [11], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:53.071 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [woshixiaomin , SpannableStringBuilder], start = [0], end = [12], dest = [], dstart = [0], dend = [0]
2021-12-10 15:24:53.324 13209-13209/com.boom.inputmethodtest D/EditTextDemo: filter() called with: source = [woshixiaoming , SpannableStringBuilder], start = [0], end = [13], dest = [], dstart = [0], dend = [0]

最终效果:

以上便是该问题的整体解决思路,正如后面所讲的,此优化方式会出现拼音法输入中文时,用户键入的拼音不可见;如各位有更好的解决思路,欢迎沟通留言,THX!

一种Android输入框待输入字符去除文本监听回调的方案思路相关推荐

  1. android设置输入框输入字符限制,Android EditText限制输入字符的方法总结

    Android EditText限制输入字符的方法总结 最近项目要求限制密码输入的字符类型, 例如不能输入中文.   现在总结一下EditText的各种实现方式,  以比较各种方法的优劣. 第一种方式 ...

  2. android 通过GPS获取用户地理位置并监听位置变化

    1 Location Manager 管理服务 2 Location Provider 提供数据的content provider 方式一:GPS 特点:精度高,耗电量大,不耗费流量 权限<us ...

  3. 献给android原生应用层开发初学者技术架构选型和整合的方案思路(二)

    前篇<献给android原生应用层开发初学者技术架构选型和整合的方案思路(一)> 本篇侧重于安卓创建的创建和后续 demo 中用到的 lib 在 gradle 中的依赖配置,本文假设您已经 ...

  4. Android 自定义监听回调Listener

    自定义监听回调Listener 使用场景:在某一页面布局中,除了原生View还有自定义View,当触发自定义View的击事件时,该页面的原生布局需要同步进行处理 demo:主页面有两部分UI,一部分是 ...

  5. Android Activity 生命周期详解及监听

    前言 系列文章: Android Activity 与View 的互动思考 Android Activity 生命周期详解及监听 Android onSaveInstanceState/onResto ...

  6. android 输入框不可输入中文,Android学习笔记 —— Android 开发中,限制 EditText 输入框不能输入中文(汉字)...

    今天在练习开发一个小项目的时候,需要限制 EditText 输入框不能输入中文(汉字),在网上找了很多例子, 结合自己的实际,终于完成了这一功能.现在把代码记录下来,方便以后查找! 首先是xml布局文 ...

  7. Android EditText控制输入字符限制的方法

    EditText控制输入字符限制的方法 1 EditText的inputType属性 inputType属性用于设置EditText的输入类型,如number,只能输入数字,软键盘为数字键盘 1.1 ...

  8. android输入框EditText输入银行卡,输入手机,输入身份证格式化的实现

    SpaceTextWatcher android输入框输入银行卡,输入手机,输入身份证格式化的实现 项目地址 SpaceTextWatcher 实现方式 @Overridepublic void be ...

  9. html输入框只能输入文字,input文本框强制输入指定文字的方法以及IE11的兼容

    背景:最近开发的韩国项目,在用户姓名输入框一栏中,要求只能输入韩文,通常用到onkeyup和onafterpaste两个事件来触发方法,并在方法中进行校验,但是在IE浏览器中,出现了一种情况,就是韩文 ...

最新文章

  1. git add remote_Git每次更新提交都提示输入密码怎么解决?
  2. listen()与accept()函数的区别
  3. php.ini文件可以复制吗,php安装完成以后要复制php.ini文件
  4. 整理一周的Python全品类资料包含100本电子书,还有独家实战项目源码公开!
  5. 关于 VC 执行顺序
  6. jpa和hibernate_从JPA到Hibernate的旧版和增强型标识符生成器
  7. java 工程路径_java 项目的路径详情
  8. Selenium 新手入门(C#)1. 用vs运行调用Selenium打开页面
  9. jQuery和$、jQuery(function(){})和(function(){})(jQuery)
  10. iphone一键转移_换iPhone数据转移太麻烦?用腾讯电脑管家iPhone助手一键搞定
  11. 稀疏表示 过完备字典
  12. OmniPlayer Pro for Mac(全能视频播放器)
  13. 怎么修改html后缀名,在win7系统下如何修改文件后缀名?win7修改文件后缀名html方法...
  14. SQL(09)_UNIQUE 约束
  15. python的基本数据类型关键字_Python3 基本数据类型
  16. 爱奇艺,美团打车Java岗面试经历,这些问题我是真没抗住
  17. VS2013打包Windows程序部署教程
  18. SVC(可分层视频编解码)
  19. 洛谷 P1007独木桥 C语言
  20. php stortm 老是闪退,pr加载界面闪退的原因是什么?

热门文章

  1. 项目质量管理之持续改进
  2. 聚类算法K-Means K-Medoids GMM Spectral clustering,Ncut
  3. Common Lisp学习之一:初识CL的语法与语义
  4. [sd card] sd card初始化流程
  5. HTC G7(Desire) Android 2.2 开启APP2SD最安全的方法(软件安装到SD卡)
  6. android 控制移动网络开关
  7. BZOJ4811: [Ynoi2017]由乃的OJ 重链剖分
  8. matlab 天线设计 泰勒加权_泰勒加权功分器
  9. juicy-potato Windows提权之访问令牌操纵
  10. vue 传参获取数据