转载请注明,大飞:http://blog.csdn.net/rflyee/article/details/38856539

限定EditText输入个数的解决方式非常多,可是一般主要考虑两点。也就是处理两件事:

(1)不同语言字符(英文、中文等)处理方式

(2)输入字符达到数目后,是否仍然同意用户输入

第一点,涉及的东东事实上蛮多,不同语言在不同编码中占领字节数等,不同语言在U8等编码的表示范围等,这一整块知识非常丰富,自己临时没有理的特别顺。稍后整理再说吧。

第二点。眼下主流app的处理方案也各有不同,qq5.0曾经的版本号,发表说说貌似是没有字数限制的(我试了一个350字左右的照样发),5.0以后限制了,这样假设用户输入字数超过限制便显示负数,可是仍然同意用户输入,就是不能发表了。这样就把处理权所有交给用户了,事实上更省事了!

实现吧。

方法一:

布局中限制。

android:maxLength="10"  // 即限制最大输入字符个数为10。

(1)中英文都算一个字符。

(2)字数到,不能输入



方法二:

InputFilter限制,同布局中限制类似。

editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(10)});

(1)中英文都算一个字符。

(2)字数到。不能输入



方法三:

TextWatcher限制。

这里假设字数达到限制仍然同意用户输入的情况不多说,好实现。

crash问题:使用搜狗输入法时,在字数将要或者已经达到限制之后,一次输入大量中文(不按空格,一直打字。知道搜狗的缓存字符达到上限)。 crash。stackoverflow 内存溢出。呵呵,百度输入法不会哈。

解决:监听器中动态去除、加入就ok了。见下边方案一



方案一,中文按两个,英文按一个。个数到限制,用户不能输入

private TextWatcher textWatcher = new TextWatcher() {
private int editStart;
private int editEnd;
private int maxLen = 10; // the max byte
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
Log.d("TextChanged", "---->beforeTextChanged : start = " + start + " count = " + count + " after = " + after);
} @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
} @Override
public void afterTextChanged(Editable s) {
editStart = opinion.getSelectionStart();
editEnd = opinion.getSelectionEnd();
// 先去掉监听器,否则会出现栈溢出
opinion.removeTextChangedListener(textWatcher);
if (!TextUtils.isEmpty(opinion.getText())) {
String etstring = opinion.getText().toString().trim();
while (calculateLength(s.toString()) > maxLen) {
s.delete(editStart - 1, editEnd);
editStart--;
editEnd--;
Log.d("TextChanged", "editStart = " + editStart + " editEnd = " + editEnd);
}
} opinion.setText(s);
opinion.setSelection(editStart); // 恢复监听器
opinion.addTextChangedListener(textWatcher);
// end by zyf --------------------------
}
private int calculateLength(String etstring) {
char[] ch = etstring.toCharArray(); int varlength = 0;
for (int i = 0; i < ch.length; i++) {
// changed by zyf 0825 , bug 6918,增加中文标点范围 , TODO 标点范围有待详细化
if ((ch[i] >= 0x2E80 && ch[i] <= 0xFE4F) || (ch[i] >= 0xA13F && ch[i] <= 0xAA40) || ch[i] >= 0x80) { // 中文字符范围0x4e00 0x9fbb
varlength = varlength + 2;
} else {
varlength++;
}
}
Log.d("TextChanged", "varlength = " + varlength);
// 这里也能够使用getBytes,更准确嘛
// varlength = etstring.getBytes(CharSet.forName("GBK")).lenght;// 编码依据自己的需求,注意u8中文占3个字节...
return varlength;
}
};

补加:

事实上在字符超出的情况下不一个一个删。而是将多余字符一次性全删掉。就可以避免内存溢出的问题,例如以下面方式。(暂未在afterTextChanged处理验证。可自行尝试,兴许补上)。方案二同理,仅仅只是处理截取方式不同罢了。(注:中英字符问题如以上方案自行处理)

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String str = s.toString();
if (length > maxNum) {
ToastUtil.show(mContext, "超出字数限制!");
str = str.substring(0, maxNum);
etContent.setText(str);
etContent.setSelection(str.length());
}
}

方案二

// 达到限制字数后,假设在文字中间输入文字或者空格。最后的字符会被删除

titleTv.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) {
// add by zyf 0825 . 多余的从新输入的位置删除,而不是最后
editStart = opinion.getSelectionStart();
editEnd = opinion.getSelectionEnd(); if (!TextUtils.isEmpty(titleTv.getText())) {
int varlength = 0;
int size = 0;
String etstring = titleTv.getText().toString().trim();
char[] ch = etstring.toCharArray();
for (int i = 0; i < ch.length; i++) {
size++;
if (ch[i] >= 0x4e00 && ch[i] <= 0x9fbb) {
varlength = varlength + 2;
} else
varlength++;
if (varlength > 80) {
break;
}
}
if (varlength > 80) {
s.delete(size - 1, etstring.length());
// add by zyf 0825 . 多余的从新输入的位置删除,而不是最后
// s.delete(editStart - 1, editEnd); // crash stackoverflow,解决方法參考上边方案一
}
}
} });

转载请注明,大飞:http://blog.csdn.net/rflyee/article/details/38856539

Android EditText输入字数限制总结(包含中文输入内存溢出的解决方法)的更多相关文章

  1. 【移动开发】EditText输入字数限制总结(包括中文输入内存溢出的解决方法)

    限定EditText输入个数的解决方案很多,但是一般主要考虑两点,也就是处理两件事:(1)不同语言字符(英文.中文等)处理方式(2)输入字符达到数目后,是否仍然允许用户输入 第一点,涉及的东东其实蛮多 ...

  2. [转]asp.net URL中包含中文参数造成乱码的解决方法

    本文转自:http://www.jb51.net/article/22437.htm 问题: 前段时间,在系统中做了一个类似于友情链接的功能块,一直运行良好,直到有一天加了类似于以下的链接地址:htt ...

  3. android通过BitmapFactory.decodeFile获取图片bitmap报内存溢出的解决办法

    android通过BitmapFactory.decodeFile获取图片bitmap报内存溢出的解决办法 原方法: public static Bitmap getSmallBitmap(Strin ...

  4. URL中含有+号,出现错误“请求筛选模块被配置为拒绝包含双重转义序列的请求”的解决方法

    搜索关键词中含空格,提交后被自动转成了“+”号,报如下错误: HTTP 错误 404.11 - Not Found 请求筛选模块被配置为拒绝包含双重转义序列的请求. 解决方法: 在web.config ...

  5. Python3:读取配置dbconfig.ini(含有中文)显示乱码的解决方法

    Python3:读取配置dbconfig.ini(含有中文)显示乱码的解决方法 一.原因 Python 3 中虽有encoding 参数,但是对于有BOM(如Windows下用记事本指定为utf-8) ...

  6. Python中文注释报错的解决方法

    在Python的程序中加了中文注释会报错 解决方法是:在程序的最开始位置加入 # -- coding: utf-8 --

  7. [Android开发常见问题-11] Unable to execute dex: Multiple dex files define 解决方法

    最近在开发一个工程,其中用到了一个开源的库项目Android-ViewPagerIndicator. 这个项目是作为一个库出现的,如下图: 这个项目中包含了android-support-v4.jar ...

  8. ubuntu中出现:程序 'java' 已包含在下列软件包中的解决方法

    已经安装sun java 在终端中输入java,出现以下提示: 程序 'java' 已包含在下列软件包中: * default-jre * gcj-4.8-jre-headless * gcj-4.9 ...

  9. mysql for Mac 下创建数据表中文显示为?的解决方法

    在我的绝版Mac mini下安装了mysql 5.7版本,实例中,在通过load data 导入数据时发现表中的中文显示为  ? 通过百度,发现多个版本的解决方法,将其中一个成功解决的方法贴上来: 大 ...

随机推荐

  1. codeforces 739D

    这题码量好大…… 首先思考如何构造,不难找到一下两个条件 1. 在长度为i的环上的点一定是i的倍数个 2. 到达长度i的环的点集距离一定是连续的 第一个条件是很好搞的,关键是第二个条件. 因为存在着x ...

  2. HDU 1181.变形课-并查集

    变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submis ...

  3. unused import statement android studio 解决方法

    解决方法:“file”-->“invalidate caches/restart” 解决 感谢大神的解答

  4. String和StringBuffer的机制差别

    String是不可变的,StringBuffer是可变的:StringBuffer是线程安全的,StringBuilder是非线程安全的. 因而在大部分情况下字符串的拼接速度为:StringBuild ...

  5. [xsy1294]sub

    给出一棵$N$个节点的无根树,节点$i$有权值$v_i$.现在有$M$次操作,操作有如下两种: $1\ x\ y$ 将节点$x$的权值$v_x$修改为$y$ $2$ 选择一个联通块(也可以不选择),使 ...

  6. 【KMP】BZOJ3670-[Noi2014]动物园

    [题目大意][依然借用别人的概括]给定一个长为L的字符串(L<=100W),求一个num数组,num[i]表示长度为i的前缀中字符串S’的数量,其中S‘既是该前缀的前缀也是该前缀的后缀,且|S' ...

  7. [HDU6271]Master of Connected Component

    [HDU6271]Master of Connected Component 题目大意: 给出两棵\(n(n\le10000)\)个结点的以\(1\)为根的树\(T_a,T_b\),和一个拥有\(m( ...

  8. 1.3(Spring学习笔记)Spring-AOP

    一.AOP简介 AOP面向切面编程,是将一种横向抽取机制,将多个类中需要使用的方法提取出来. 例如,这里有两个类,一个Cat,一个Dog,动物都需要吃饭睡觉,如果按照传统的思想. 给两类中都添加吃饭和 ...

  9. BlockTransferService 实现

    spark的block管理是通过BlockTransferService定义的方法从远端获取block.将block存储到远程节点.shuffleclient生成过程就会引入blockTransfer ...

  10. Linux下数组遍历

    声明一个数组变量 直接赋值: array[]=”Zero” array[]=”One” array[]=”Two” declare声明: declare -a array 小括号空格法: array= ...