博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EditText输入字数限制的三个方法
阅读量:6801 次
发布时间:2019-06-26

本文共 3437 字,大约阅读时间需要 11 分钟。

hot3.png

限定EditText输入个数的解决方案很多,但是一般主要考虑两点,也就是处理两件事:

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

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

第一点,涉及的东东其实蛮多,不同语言在不同编码中占据字节数等,不同语言在U8等编码的表示范围等,这一整块知识很丰富,

自己暂时没有理的特别顺,稍后整理再说吧。

第二点,目前主流app的处理方案也各有不同,qq5.0以前的版本,发表说说貌似是没有字数限制的(我试了一个350字左右的照样发),

5.0以后限制了,这样如果用户输入字数超过限制便显示负数,但是仍然允许用户输入,就是不能发表了。这样就把处理权全部交给用户了,

其实更省事了!

实现吧。

方法一:

布局中限制。

[java] view plaincopy

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

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

(2)字数到,不能输入

方法二:

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

[java] view plaincopy

  1. editText.setFilters(new InputFilter[]{

    new InputFilter.LengthFilter(10)});  

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

(2)字数到,不能输入

方法三:

TextWatcher限制。这里如果字数达到限制仍然允许用户输入的情况不多说,好实现。

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

crash,stackoverflow 内存溢出。呵呵,百度输入法不会哈。

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

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

[java] view plaincopy

  1. private TextWatcher textWatcher = new TextWatcher() {  

  2.     private int editStart;  

  3.     private int editEnd;  

  4.     private int maxLen = 10; // the max byte  

  5.     @Override  

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

  7.         Log.d(TextChanged, ---->beforeTextChanged : start =  + start +  count =  + count +  after =  + after);  

  8.     }  

  9.   

  10.     @Override  

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

  12.     }  

  13.   

  14.     @Override  

  15.     public void afterTextChanged(Editable s) {  

  16.         editStart = opinion.getSelectionStart();  

  17.         editEnd = opinion.getSelectionEnd();  

  18.         // 先去掉监听器,否则会出现栈溢出  

  19.         opinion.removeTextChangedListener(textWatcher);  

  20.         if (!TextUtils.isEmpty(opinion.getText())) {  

  21.             String etstring = opinion.getText().toString().trim();  

  22.             while (calculateLength(s.toString()) > maxLen) {  

  23.                 s.delete(editStart - 1, editEnd);  

  24.                 editStart--;  

  25.                 editEnd--;  

  26.                 Log.d(TextChanged, editStart =  + editStart +  editEnd =  + editEnd);  

  27.             }  

  28.         }  

  29.   

  30.         opinion.setText(s);  

  31.         opinion.setSelection(editStart);  

  32.   

  33.         // 恢复监听器  

  34.         opinion.addTextChangedListener(textWatcher);  

  35.         // end by zyf --------------------------  

  36.     }  

  37.     private int calculateLength(String etstring) {  

  38.         char[] ch = etstring.toCharArray();  

  39.   

  40.         int varlength = 0;  

  41.         for (int i = 0; i < ch.length; i++) {  

  42.             // changed by zyf 0825 , bug 6918,加入中文标点范围 , TODO 标点范围有待具体化  

  43.             if ((ch[i] >= 0x2E80 && ch[i] <= 0xFE4F) || (ch[i] >= 0xA13F && ch[i] <= 0xAA40) || ch[i] >= 0x80) { // 中文字符范围0x4e00 0x9fbb  

  44.                 varlength = varlength + 2;  

  45.             } else {  

  46.                 varlength++;  

  47.             }  

  48.         }  

  49.         Log.d(TextChanged, varlength =  + varlength);  

  50.         // 这里也可以使用getBytes,更准确嘛  

  51.         // varlength = etstring.getBytes(CharSet.forName(GBK)).lenght;// 编码根据自己的需求,注意u8中文占3个字节...  

  52.         return varlength;  

  53.     }  

  54. };  

方案二

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

[java] view plaincopy

  1. titleTv.addTextChangedListener(new TextWatcher() {  

  2.   

  3.     @Override  

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

  5.   

  6.     }  

  7.   

  8.     @Override  

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

  10.   

  11.     }  

  12.   

  13.     @Override  

  14.     public void afterTextChanged(Editable s) {  

  15.          // add by zyf 0825 . 多余的从新输入的位置删除,而不是最后  

  16.            editStart = opinion.getSelectionStart();  

  17.            editEnd = opinion.getSelectionEnd();  

  18.   

  19.         if (!TextUtils.isEmpty(titleTv.getText())) {  

  20.             int varlength = 0;  

  21.             int size = 0;  

  22.             String etstring = titleTv.getText().toString().trim();  

  23.             char[] ch = etstring.toCharArray();  

  24.             for (int i = 0; i < ch.length; i++) {  

  25.                 size++;  

  26.                 if (ch[i] >= 0x4e00 && ch[i] <= 0x9fbb) {  

  27.                     varlength = varlength + 2;  

  28.                 } else  

  29.                     varlength++;  

  30.                 if (varlength > 80) {  

  31.                     break;  

  32.                 }  

  33.             }  

  34.             if (varlength > 80) {  

  35.                  s.delete(size - 1, etstring.length());  

  36.                  // add by zyf 0825 . 多余的从新输入的位置删除,而不是最后  

  37.                  // s.delete(editStart - 1, editEnd); // crash stackoverflow,解决方法参考上边方案一  

  38.             }  

  39.         }  

  40.     }  

  41.   

  42. });   

转载于:https://my.oschina.net/u/1244156/blog/351422

你可能感兴趣的文章
利用node.js和mongodb为你的app写一个web服务
查看>>
Rails 3 Authlogic: Could not find generator ses...
查看>>
iOS静态库的那些坑
查看>>
IOS-APP提交上架流程(新手必看!2016年3月1日最新版)
查看>>
oracle rman 2
查看>>
hyper-v下NIC实验出现的问题
查看>>
shell 显示文件的行数
查看>>
Linux:常规目录操作
查看>>
2016年2月书单
查看>>
redis存储 100 条最新的记录
查看>>
There is no reason to wait
查看>>
tomcat 配置单向加密连接器-01
查看>>
数据库备份恢复 mysqldump, source
查看>>
花生壳与网络地址转换
查看>>
4.信号与传输介质
查看>>
免费资源下载:Simplycons图标集
查看>>
MySQL 性能医生:OrzDBA
查看>>
【设计模式】代理模式
查看>>
linux脚本获取系统信息(选自实验楼实验)
查看>>
俄罗斯游戏软件:C语言应用初步感受
查看>>