android 只能输入汉字,EditText限制输入的几种方式及只显示中文汉字的做法

前段时间项目中有个需求是要求只能输入汉字,并且不能输入偏旁部首,于是总结了下EditText限制输入的几种方式,但是对于语音输入的还没找到好的解决方案:

通过设置EditText的inputType来限制,可以在xml或者java代码中设置:

在xml中设置:android:inputType="textPassword"

在java代码中设置: mEditText.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);

可以通过设置不同属性来限制输入内容。

通过设置EditText的android:digits 属性来限制可输入的内容,但需要把允许输入的内容全都罗列出来,只适合允许输入少数限制的情况,如只允许输入数字,像这种只能输入汉字的情况明显不适合,总不能把几千个汉字全都罗列出来吧。

通过InputFilter来限制。

/**

* EditText限制只能输入汉字

*/

public InputFilter getInputFilter() {

InputFilter filter = new InputFilter() {

public CharSequence filter(CharSequence source, int start, int end,

Spanned dest, int dstart, int dend) {

if (TextUtils.isEmpty(source)){

return "";

}

for (int i = start; i < end; i++) {

if (stringFilterChinese(source) && !source.toString().contains("。") && !source.toString ().contains(",")) {

return "";

} else if (CHINESE_RADICAL_DIGISTS.contains(source)) {

return "";

}

}

return null;

}

};

return filter;

}

/**

* 限制只能输入汉字,过滤非汉字

*

* @param str 输入值

* @return true 非汉字;false 汉字

*/

public boolean stringFilterChinese(CharSequence str) {

//只允许汉字,正则表达式匹配出所有非汉字

String regEx = "[^\u4E00-\u9FA5]";

Pattern p = Pattern.compile(regEx);

Matcher m = p.matcher(str);

if (m.find()) {

return true;

} else {

return false;

}

}

mEdtAddDictation.setFilters(new InputFilter[]{getInputFilter()});

查看TextView的源码,在setText中通过调用filter()过滤了相关内容:

private void setText(CharSequence text, BufferType type,boolean notifyBefore, int oldlen) {

...

int n = mFilters.length;

for (int i = 0; i < n; i++) {

CharSequence out = mFilters[i].filter(text, 0, text.length(), EMPTY_SPANNED, 0, 0);

if (out != null) {

text = out;

}

}

...

}

通过TextWatch来限制输入。

mEdtAddDictation.addTextChangedListener(mTextWatcher);

private TextWatcher mTextWatcher = new TextWatcher() {

@Override

public void beforeTextChanged(CharSequence s, int start, int count, int after) {

this.temp = s;

}

@Override

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

}

@Override

public void afterTextChanged(Editable editable) {

String words = editable.toString().trim();

if (TextUtils.isEmpty(words)) {

mBtnAddSure.setEnabled(false);

} else {

mBtnAddSure.setEnabled(true);

}

if (TextUtils.isEmpty(words)) {

return;

}

String newWords = words;

newWords = StringUtils.clearLimitStr(StringUtils.DEFAULT_REGEX_LIMIT_CHINESE,newWords);

newWords = StringUtils.clearLimitStr(StringUtils.CHINESE_RADICAL_DIGISTS,newWords);

boolean isChange = false;

if (!TextUtils.equals(words,newWords)){

isChange = true;

words = newWords;

}

if (words.length() > MAX_INPUT_LIMIT) {

ToastUtils.getInstance(AddDictationWordsActivity.this).s(R.string.dictation_add_word_limit);

words = words.substring(0, MAX_INPUT_LIMIT);

isChange = true;

}

if (isChange) {

mEdtAddDictation.removeTextChangedListener(this);

// et.setText方法可能会引起键盘变化,所以用editable.replace来显示内容

editable.replace(0, editable.length(), words.trim());

mEdtAddDictation.addTextChangedListener(this);

}

}

};

/**

* 清除不符合条件的内容

*

* @param regex

* @return

*/

public static String clearLimitStr(String regex, String str) {

return str.replaceAll(regex, "");

}

/**

* 默认的筛选条件(正则:只能输入中文)

*/

public static String DEFAULT_REGEX_LIMIT_CHINESE = "[^\u4E00-\u9FA5]";

/**

* 偏旁部首

*/

public static final String CHINESE_RADICAL_DIGISTS = "[犭凵巛冖氵廴纟讠礻亻钅宀亠忄辶弋饣刂阝冫卩疒艹疋豸冂匸扌丬屮衤勹彳彡]";

通过自定义InputConnectionWrapper来限制输入。

步骤:

(1)自定义EditText,重载onCreateInputConnection方法,它需要返回一个InputConnection对象;

(2)继承于InputConnectionWrapper, 实现自己的InputConnection 并且在onCreateInputConnection中返回。

(3)在自定义的InputConnectionWrapper类中,实现输入法输入和按键事件的拦截。

由于InputConnection是在文本显示之前进行调用,因此可以通过重写其中的方法修改要显示的内容。

/**

* @author zhangshao

* @desc 只能输入汉字的输入框

* @time 2018/11/8 18:09

*/

@SuppressLint("AppCompatCustomView")

public class ChineseLimitEditText extends EditText {

public ChineseLimitEditText(Context context) {

super(context);

}

public ChineseLimitEditText(Context context, AttributeSet attrs) {

super(context, attrs);

}

public ChineseLimitEditText(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

/**

* 输入法

*

* @param outAttrs

* @return

*/

@Override

public InputConnection onCreateInputConnection(EditorInfo outAttrs) {

return new InnerInputConnecttion(super.onCreateInputConnection(outAttrs),

false);

}

class InnerInputConnecttion extends InputConnectionWrapper implements InputConnection {

public InnerInputConnecttion(InputConnection target, boolean mutable) {

super(target, mutable);

}

/**

* 对输入的内容进行拦截

*

* @param text

* @param newCursorPosition

* @return

*/

@Override

public boolean commitText(CharSequence text, int newCursorPosition) {

// 只能输入汉字

if (!TextUtils.isEmpty(text) && (!StringUtils.isContainChinese(text.toString()) ||

StringUtils.isContainRadical(text.toString()))) {

return false;

}

return super.commitText(text, newCursorPosition);

}

@Override

public boolean sendKeyEvent(KeyEvent event) {

// 拦截换行键

return event.getKeyCode() != KeyEvent.KEYCODE_ENTER && super.sendKeyEvent(event);

}

@Override

public boolean setSelection(int start, int end) {

return super.setSelection(start, end);

}

}

}

/**

* 字符串是否包含中文

* */

public static boolean isContainChinese(String str) {

Pattern p = Pattern.compile("[\u4e00-\u9fa5]");

Matcher m = p.matcher(str);

if (m.find()) {

return true;

}

return false;

}

/**

* 字符串是否包含偏旁部首

* */

public static boolean isContainRadical(String str) {

Pattern p = Pattern.compile(CHINESE_RADICAL_DIGISTS);

Matcher m = p.matcher(str);

if (m.find()) {

return true;

}

return false;

}

拦截条件:在commitText方法中,如果执行父类的 commitText(即super.commitText(text, newCursorPosition))那么表示不拦截,如果返回false则表示拦截,

输入法的字符串则无法传送到EditText。在sendKeyEvent中,如果执行父类的sendKeyEvent(即super.sendKeyEvent(event))那么表示不拦截,如果返回false表示拦截。

不同的需求可以通过不同的限制方法组合使用,不用局限于一种。

以上几种方法都可以解决软键盘输入时只显示中文的问题,但是搜狗输入法的语音输入无法过滤,一旦在InputFilter或者TextWatch中屏蔽,那么语音输入内容会重复,目前分析的原因是:语音输入是持续输入,如果去掉相应的标点,那么输入法会检测到输入内容与缓存的不对应,会把之前的文本拿出来重新拼接在一起返回。如果有朋友有好的解决方案,还望不吝赐教!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/296812.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

plsql导出表结构到excel_plsql怎么导出表格!如何用plsql从oracle中导入导出数据

如何将plsql内多个窗口查询结果同时导出到excel内在PL/SQL工具中执行得到的可以导出放在同一个EXCEL的多个Sheet页签的&#xff0c;操骤为&#xff1a;选中其中一个结果集中数据→右键→复制到Excel→作为xls复制所有(or作为xlsx复制所有)→完成。操作截图&#xff1a;Excel展示…

史上最强悍的一张图,没有任何一个中国人能躲得开!

▲ 点击查看几乎每个家庭都会有两张地图&#xff1a;一张世界地图&#xff0c;一张中国地图。薄薄的两张纸&#xff0c;蕴藏着让每个人学会“看世界”的磅礴力量。哈佛上一任校长&#xff0c;也是300多年来唯一一位女校长德鲁吉尔平福斯特&#xff08;Drew Gilpin Faust&#x…

解决vista/win7安装windows live messenger 2011找不到wlidcli.dll及错误800488eb .

问题一&#xff1a;找不到文件wlidcli.dll。 这个问题可能是由于修改了默认的Common Files 文件夹所在磁盘造成的。默认的位置是“C:/Program Files (x86)/Common Files/microsoft shared/Windows Live”&#xff0c;比如被改到了“D:/Program Files (x86)/Common Files/micros…

Dapr牵手.NET学习笔记:可观测性-分布式跟踪

分布式跟踪在dapr里是开箱即用的&#xff0c;不需要对应用作任何一丁点的侵入式编程。之前的开发&#xff0c;如果想实现分式跟踪&#xff0c;就得在应用中埋点&#xff0c;这是一个与业务无关系的动作。dpar通过sidecar可以轻松做到这点&#xff0c;从而让程序员更多精力投入到…

mysql cookbook 1

show databases; use [database]; show tabels;GRANT ALL ON database.* TO user localhost IDENTIFIED BY password;>mysql -h localhost -p -u user;转载于:https://www.cnblogs.com/chhyong88/archive/2012/07/22/2603592.html

新人入职培训有关职场沟通的总结分享

沟通 不要越级沟通言必成三&#xff0c;超过3点记不住的。kiss原则&#xff0c;keep it simple and stupid说事实观点先说结论与重点&#xff0c;再说细节支撑结论&#xff1a;mece原则&#xff0c;穷尽且不交叉提问最好不要问是或否的问题&#xff0c;而是开放性问题。 是或否…

Android带三角形的弹窗,Android实现三角形气泡效果方式汇总

在开发过程中&#xff0c;我们可能会经常遇到这样的需求样式&#xff1a;这张图是截取京东消息通知的弹出框&#xff0c;我们可以看到右上方有个三角形的气泡效果&#xff0c;这只是其中一种&#xff0c;三角形的方向还可以是上、下、左、右。通过截图可以发现&#xff0c;气泡…

ecno是什么的缩写_美国的英文缩写是什么简写

利坚合众国简称美国&#xff0c;它的英文也是有简写的&#xff0c;就算我们不知道它的全称其缩写也不会忘记。以下是学习啦小编给大家带来美国的英文缩写&#xff0c;以供参阅。美国的英文简写美国的英文缩写&#xff1a;the United States of America (U.S.A.)美国的英文缩写&…

GDI+ 设置文本对齐方式

可通过以下语句来设置文本的对齐方式&#xff1a;StringFormat sF new StringFormat()sF.Alignment StringAlignment.Far; sF.LineAlignment StringAlignment.Far;代码&#xff1a;、View Code privatevoidForm1_Paint(objectsender, PaintEventArgs e) { …

那些视觉上骗了你的东西,你上当了吗?

全世界只有3.14 % 的人关注了爆炸吧知识世界上最离谱的错觉图&#xff0c;看完我瞎了还能不能好好的玩耍了啊&#xff01;1

微服务组件记事本:本地搭建Skywalking

最近一直在研究微服务&#xff0c;完全避免不了的是各种中间件的使用&#xff0c;打算把过程简要记录下来&#xff0c;过程很简单&#xff0c;也不会有原理和源代码级别的讲解&#xff0c;只是做下简单的知识备份。今天开始研究下链路追踪Skywalking&#xff0c;还记得之前在《…

linux nodejs 采集器,Linux记录-jstack采集namenode gc信息

#!/bin/bash#以hdfs用户执行jstack每分钟采集一次namenode gc日志#mkdir -p /tmp/jstackcd /log/hadoop/jstack_nnpid$(jps | grep -i "namenode" | awk NR1{print $1})dir/log/hadoop/jstack_nn/jstack_nn_date "%Y-%m-%d-%H"if [ ! -d ${dir} ]thenmkdir…

1.1-1.5-vim编辑器

vim是vi的升级版共有3种工作模式&#xff1a;1一般模式 2编辑模式 3命令模式a在光标后插入 i在光标前插入 o在光标下插入新行A在光标行末插入 I在光标行首插入 O在光标上插入新行$光标移动到行尾 0光标移动到行首gg光标到第一行 G光标到最后一行…

UI设计师应了解最终用户的十件事

Ubuntu Unity 刚度过了它的首个周年纪念日&#xff0c;Windows 8也即将发布&#xff0c;这一切都在清晰地说明所有的用户界面并非平等。事实上&#xff0c;创造一个可以改变计算机使用方式、出色的设计是很有可能的——但如果不重视用户体验&#xff0c;这个设计在证明它出色之…

优化见解

所谓的最优化&#xff0c;那就是实现资源的充分利用。而充分利用资源的方法&#xff0c;并不是让优势资源发挥更大潜力&#xff0c;而是让不同资源得到适当地配置&#xff0c;否则也达不到最优化。这就好比摩托车的能效是发挥到极致了&#xff0c;但并不表示整个过程就是极致。…

python路径长度限制_[windows] python 帮忙打开文件名太长限制

不知道你是否有遇到&#xff0c;在windows复制/移动文件的时候发生路径太长以致于无法复制/移动的情况&#xff1f;不知道你是否有遇到&#xff0c;在windows复制/移动文件的时候发生路径太长以致于无法复制/移动的情况&#xff1f;我大概每年发生个四、五次&#xff0c;在备份…

马斯克发布脑机接口重大突破:蓝牙连接,一小时植入,已获FDA认证,人体实验在即...

全世界只有3.14 % 的人关注了爆炸吧知识综合整理自&#xff1a;机器之心、量子位、智东西编辑&#xff1a;知识君伊隆 马斯克神秘的脑机接口公司 Neuralink&#xff0c;终于向人们展示了自己首款可以「进入人体」的产品。今日&#xff0c;在 Neuralink 总部的发布会活动上&…

如何在android客户端中做到自动检查数据更新?,UpdateHelper

软件简介UpdateHelper 是一个为了简化Android App的迭代升级开发的AndroidLibrary&#xff0c;任何一个项目只要引入这个library便集成了在线检查新版本的功能以及下载APK功能&#xff0c;仅需两行代码即可搞定。UpdateHelpers要怎么使用&#xff1f;1.首先服务器端需要提供一个…

【另类见解】那些要保证缓存和数据库数据一致性的最后怎么了?

“现在如果说不出几句如何保证数据一致性方案的话&#xff0c;觉得出去面试都丢人,尤其是缓存和数据库的数据一致性“全程无图&#xff0c;请谨慎阅读缓存对于程序性能而言&#xff0c;无疑是个杀手锏&#xff0c;但不是完美的解决方案。关键在于缓存的物理位置和数据真实保存的…

redhat enterprise linux 5 上安装openoffice3.0 1

1.首先根据自己的计算机情况去下载相应的openoffice.org3.1 for liunx中文版 网址&#xff1a;http://zh.openoffice.org/new/zh_cn/downloads.html 2.解压缩软件&#xff0c;在终端进入RPMS文件中&#xff0c;安装 Java-runtime 支持包。 jre-6-linux-i586.rpm &#xff03;ta…