Android字数限制的EditText实现方案研究
在应用开发中,有时需要实现有字数限制的EditText,首先来分析下市面上存在的类似实现方案吧,好有个感性的认识。
【方案一:腾讯微博】
每个中文字符算一个字数,每两个英文字符算一个字数,当用户输入内容时,实时显示剩余的字数,当超出字数限制时,剩余字数显示为负数,但此时用户仍然可以继续在EditText中输入内容,直到用户点击菜单中的“发送”按钮时,才会弹出对话框或者Toast显示用户输入的字数超标,如下图所示:

这个方案实现起来很简单,只需要给EditText设置TextWatcher监听器,然后判断输入的是中文字符还是英文字符,实时更新剩余输入字数显示即可,不需要限制EditText的输入。
【方案二:百度旅游】
中英文字符都算一个字数,当用户输入内容时,实时显示剩余的字数,当超出字数限制时,剩余字数显示为0,不会出现负数的情况,这时EditText再也不接收用户输入的任何内容了。

这个方案由于中英文都占一个字数,因此可以直接给EditText设置InputFilter.LengthFilter,这时LengthFilter会自动帮EditText限制用户输入的内容;再给EditText设置TextWatcher监听器,就可以实时更新剩余字数了。
本文综合上面两个方案,给出【方案三】,每个中文字符算一个字数,每两个英文字符算一个字数,当用户输入内容时,实时显示剩余的字数,当超出字数限制时,剩余字数显示为0,不会出现负数的情况,这时EditText再也不接收用户输入的任何内容了。
方案三可用于app需要集成第三方sns分享功能,且必须自己实现分享界面的情况。由于中英文所占的字数不一样,就不能使用LengthFilter来限制用户再EditText中输入内容(因为在用户完成内容输入之前,是不知道要给lengthFilter设置的最大值的)。因此只能在TextWatcher中做些手脚了。方案三界面如下:

- package com.hust.demo;
- import android.app.Activity;
- import android.os.Bundle;
- import android.text.Editable;
- import android.text.TextWatcher;
- import android.widget.EditText;
- import android.widget.TextView;
- public class MainActivity extends Activity {
- private EditText mEditText = null;
- private TextView mTextView = null;
- private static final int MAX_COUNT = 140;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mEditText = (EditText) findViewById(R.id.content);
- mEditText.addTextChangedListener(mTextWatcher);
- mEditText.setSelection(mEditText.length()); // 将光标移动最后一个字符后面
- mTextView = (TextView) findViewById(R.id.count);
- setLeftCount();
- }
- private TextWatcher mTextWatcher = new TextWatcher() {
- private int editStart;
- private int editEnd;
- public void afterTextChanged(Editable s) {
- editStart = mEditText.getSelectionStart();
- editEnd = mEditText.getSelectionEnd();
- // 先去掉监听器,否则会出现栈溢出
- mEditText.removeTextChangedListener(mTextWatcher);
- // 注意这里只能每次都对整个EditText的内容求长度,不能对删除的单个字符求长度
- // 因为是中英文混合,单个字符而言,calculateLength函数都会返回1
- while (calculateLength(s.toString()) > MAX_COUNT) { // 当输入字符个数超过限制的大小时,进行截断操作
- s.delete(editStart - 1, editEnd);
- editStart--;
- editEnd--;
- }
- // mEditText.setText(s);将这行代码注释掉就不会出现后面所说的输入法在数字界面自动跳转回主界面的问题了,多谢@ainiyidiandian的提醒
- mEditText.setSelection(editStart);
- // 恢复监听器
- mEditText.addTextChangedListener(mTextWatcher);
- setLeftCount();
- }
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- }
- public void onTextChanged(CharSequence s, int start, int before,
- int count) {
- }
- };
- /**
- * 计算分享内容的字数,一个汉字=两个英文字母,一个中文标点=两个英文标点 注意:该函数的不适用于对单个字符进行计算,因为单个字符四舍五入后都是1
- *
- * @param c
- * @return
- */
- private long calculateLength(CharSequence c) {
- double len = 0;
- for (int i = 0; i < c.length(); i++) {
- int tmp = (int) c.charAt(i);
- if (tmp > 0 && tmp < 127) {
- len += 0.5;
- } else {
- len++;
- }
- }
- return Math.round(len);
- }
- /**
- * 刷新剩余输入字数,最大值新浪微博是140个字,人人网是200个字
- */
- private void setLeftCount() {
- mTextView.setText(String.valueOf((MAX_COUNT - getInputCount())));
- }
- /**
- * 获取用户输入的分享内容字数
- *
- * @return
- */
- private long getInputCount() {
- return calculateLength(mEditText.getText().toString());
- }
- }
但是上面代码存在一个bug,给EditText设置TextWatcher之后,由于afterTextChanged的代码实现会导致输入法界面刷新,从而使得每次输入字符,输入法界面都会跳转到他的主界面去,
例如我们当我们要输入数字时,首先要转到数字输入界面,正常情况下可以连续输入多个数字,数字输入完成后,界面仍然维持在数字输入界面,输入数字1前后界面对比图(正常情况):

而给EditText设置我们定义的Textwatcher监听器之后,在数字输入界面,每输入一个数字,输入法都会跳回主界面,需要用户再点击才能回到数字输入界面,如下图所示(引入的bug),也是输入数字1前后界面对比图:

- while (calculateLength(s.toString()) > MAX_COUNT) { // 当输入字符个数超过限制的大小时,进行截断操作
- s.delete(editStart - 1, editEnd);
- editStart--;
- editEnd--;
- }
这时Demo出现Crash,异常信息如下:

Android字数限制的EditText实现方案研究的更多相关文章
- Android键盘面板冲突 布局闪动处理方案
转:来自Android键盘面板冲突 布局闪动处理方案 起源,之前在微信工作的时候,为了给用户带来更好的基础体验,做了很多尝试,踩了很多输入法的坑,特别是动态调整键盘高度,二级页面是透明背景,魅族早期的 ...
- Android开发UI之EditText+DatePicker带日期选择器的编辑框
1. 声明EditText变量,并关联到相应控件上 private EditText sellStartTime; private EditText sellEndTime; sellStartTim ...
- 【转】android 中如何限制 EditText 最大输入字符数
原文网址:http://blog.csdn.net/fulinwsuafcie/article/details/7437768 方法一: 在 xml 文件中设置文本编辑框属性作字符数限制 如:andr ...
- android 中如何限制 EditText 最大输入字符数
方法一: 在 xml 文件中设置文本编辑框属性作字符数限制 如:android:maxLength="10" 即限制最大输入字符个数为10 方法二: 在代码中使用InputFilt ...
- Android高清巨图加载方案
1.今天看了鸿洋的<Android高清巨图加载方案>一文,对加载高清巨图时的解决方案有了一定的认识. 思路为: 提供一个设置图片的入口. 重写onTouchEvent,在里面根据用户移动的 ...
- android 实现点击edittext的“小眼睛”切换明密文
android 实现点击edittext的“小眼睛”切换明密文 版权声明:本文为博主原创文章,未经博主允许不得转载. 很多时候,我们为了用户的隐私安全,需要在密码输入的时候,显示密文.为了更 ...
- Android按键添加和处理的方案
Android按键添加和处理的方案 版本号 说明 作者 日期 1.0 Android按键添加和处理的方案 Sky Wang 2013/06/18 需求:Android机器上有个W ...
- Android之Android apk动态加载机制的研究(二):资源加载和activity生命周期管理
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/23387079 (来自singwhatiwanna的csdn博客) 前言 为了 ...
- 【转】实践最有效的提高Android Studio运行、编译速度方案
原文:https://blog.csdn.net/xwh_1230/article/details/60961723 实践最有效的提高Android Studio运行.编译速度方案 最有效提升Andr ...
随机推荐
- 配置Samba服务
1. samba服务用在什么地方?samba服务用于把Linux服务器上的文件或者打印接共享给windows或者Linux.2. 在samba服务的配置文件中,[global]配置部分的securit ...
- ComboTree( 树型下拉框) 组件
本节课重点了解EasyUI中Tree(树)组件的使用方法, 这个组件依赖于Combo(下拉框)和 Tree(树)组件.一. 加载方式//class 加载方式<select id="cc ...
- 网页HTML1
表格表单 表格, <tabale> -------表格 <tr> --------------行 <td> -- ...
- 在Ubuntu下的Apache上建立新的website,以及enable mono
1. 在Apache下建立新的web site a. $>cd /etc/apache2/ b. $>vi ports.conf 填加Listen 8090(注意不要打开8080,因为To ...
- css3圈圈进度条
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- SignalR小计
微软官方例子地址:http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr-a ...
- OpenSceneGraph FAQ
转自http://www.cnblogs.com/indif/archive/2011/04/22/2024805.html 1.地球背面的一个点,计算它在屏幕上的坐标,能得到吗? 不是被挡住了吗? ...
- html+css布局小练习w3cfuns
虽然花了很长时间,但是也知道了不少,这次也不像以前了,不知道怎么下手,虽然是照着图片做,不过也做出来了图片来自w3cfuns:网站图片url 看了w3cfuns的两天驾驭DIV+CSS 这个网站对新 ...
- 小巧实用的数字加减插件(jquery插件)
2015-12-04 近期项目需要,我将插件更新了,增加了两个参数,一个参数控制文本框是否支持输入,另一个参数则是新增了一个回调函数,返回文本框内的值.另外对代码局部重构了,优化了一下封装,需要的朋友 ...
- DEDE数据库修改后台变量
进行数据库之后找到 dede_sysconfig 这个数据表,然后查找到你要删除的dede教程变量名称. 这样就可以了