IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 一种Android输入框待输入字符去除文本监听回调的方案思路 -> 正文阅读

[移动开发]一种Android输入框待输入字符去除文本监听回调的方案思路

1. 项目需求:

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

2. 需求拆分:

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

3. 方案实施:

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

        //类型过滤器
        InputFilter typeFilter = new InputFilter() {
            @Override
            public 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() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public 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() {
            @Override
            public 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!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-11 15:50:25  更:2021-12-11 15:52:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:22:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码