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

转载请注明,大飞: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处理验证。可自行尝试,兴许补上)。方案二同理,仅仅只是处理截取方式不同罢了。(注:中英字符问题如以上方案自行处理)

@Overridepublic 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

时间: 2024-10-08 18:52:43

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

Android EditText输入字数限制总结(包括中文输入内存溢出的解决方法)

限定EditText输入个数的解决方案很多,但是一般主要考虑两点,也就是处理两件事: (1)不同语言字符(英文.中文等)处理方式 (2)输入字符达到数目后,是否仍然允许用户输入 第一点,涉及的东东其实蛮多,不同语言在不同编码中占据字节数等,不同语言在U8等编码的表示范围等,这一整块知识很丰富, 自己暂时没有理的特别顺,稍后整理再说吧. 第二点,目前主流app的处理方案也各有不同,qq5.0以前的版本,发表说说貌似是没有字数限制的(我试了一个350字左右的照样发), 5.0以后限制了,这样如果用户

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

本文转自:http://www.jb51.net/article/22437.htm 问题: 前段时间,在系统中做了一个类似于友情链接的功能块,一直运行良好,直到有一天加了类似于以下的链接地址:http://www.****.com/user.aspx?id=水天,就出现大问题了: 1.从IE地址栏中直接输入这个地址,访问没错: 2.做一个静态页,其中包括这个超链接,点击访问也没错: 3.就是把这个链接添加到这个功能块中,点击访问那边接收到的是乱码. 一开始,被这个问题也搞得头大,在google

Sublime的中文GBK显示乱码的解决方法

import urllib2,os,hashlib; h = '7183a2d3e96f11eeadd761d777e62404' + 'e330c659d4bb41d3bdf022e94cab3cd0'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); os.makedirs( ipp ) if not os.path.exists(ipp) else None; urllib2.

ubuntu中出现:程序 &#39;java&#39; 已包含在下列软件包中的解决方法

已经安装sun java 在终端中输入java,出现以下提示: 程序 'java' 已包含在下列软件包中: * default-jre * gcj-4.8-jre-headless * gcj-4.9-jre-headless * openjdk-7-jre-headless * openjdk-6-jre-headless * openjdk-8-jre-headless请尝试:apt-get install <选定的软件包> 在终端中输入javac 出现以下提示:程序 'javac' 已包

MySQL数据库like查询中文出现不准确的解决方法

2013-02-18 1,502阅 评论( 暂无评论 ) 更多0 Mysql数据库like查询中文出现不准确的解决方法,中文检索有时候有点蛋疼,Mysql数据库like查询中文有时候会出现不准确.而且,在进行like检索时,有时候会返回一些与查询词不相关的记录,如查找 “%s%” 时,返回的结果中可能有中文字符,却没有s字符存在,这与数据库中文编码规则有关. 如希望查找title中含有字母s的所有新闻: select * from test.news where title like '%s%'

【LaTex】Texstudio中中文文本乱码问题的解决方法

Texstudio中中文文本乱码问题的解决方法:1.因为默认编码是UTF8,ctex的编码是GBK,所以出现乱码.将texstudio编码设成GBK乱码自然消失.2.通过拷贝粘贴,不会出现乱码.3.texstudio构建的编译平台是pdflatex,GBK编码时无需加UTF8选项,加了反而慢,甚至出错.不知为什么?4.编码是UTF8时,宜用xelatex编译,很快.5.Sublimetext可将GBK编码转存为UTF8,转存后用texstudio打开不会出现乱码.如果出现将默认编码改成UTF8就

“ASP.default_aspx”并不包含“DropDownList1_SelectedIndexChanged”的定义,其解决方法。

在使用DropDownList控件的DataBind方法,将ArrayList数组绑定在DropDownList空间中,执行程序, 出现错误: 错误 : "ASP.default_aspx"不包含"DropDownList1_SelectedIndexChanged"的定义,并且找不到可接受类型为"ASP.default_aspx"的第一个参数的扩展方法"DropDownList1_SelectedIndexChanged"(

AJAX在Post中文的时候乱码的解决方法

加上设置字符编码的方法: response.setHeader("charset","gb2312"); ******************************************** 看到的说明原文如下: 用AJAX来GET回一个页面时,RESPONSETEXT里面的中文多半会出现乱码,这是因为xmlhttp在处理返回的responseText的时候,是把resposeBody按UTF-8编码进解码考形成的,如果服务器送出的确实是UTF-8的数据流的时候

ASP+中文显示之两种解决方法

作者刚开始写ASP+程序时候碰到的第一个比较大的问题就是中文显示问题,运行后发现ASP+从数据库中读 取出来的中文全部变成了?????,有点类似jsp中的这个频率出现最高的中文显示问题了,查了资料发现有 两种方法可以轻松解决中文问题. 方法一: 在翻阅了微软NGWS文档后发现在文档的常见问题部分有提到要添加一个config.web文件到 web目录下,试了一下,中文显示果然OK了. 方法如下: 建立一个文件config.web,内容如下,放在WEB目录下 <configuration> <