Android字数限制的EditText实现方案研究
来源:互联网 发布:淘宝证书错误怎么办 编辑:程序博客网 时间:2024/05/17 00:55
在应用开发中,有时需要实现有字数限制的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 extendsActivity { -
-
private EditText null;mEditText = -
private TextView null;mTextView = -
-
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 newmTextWatcher = TextWatcher() { -
-
private int editStart; -
-
private int editEnd; -
-
public void afterTextChanged(Editable s) { -
editStart = mEditText.getSelectionStart(); -
editEnd = mEditText.getSelectionEnd(); -
-
// 先去掉监听器,否则会出现栈溢出 -
mEditText.removeTextChangedListene r(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 ints, start, intcount, -
int after) { -
-
} -
-
public void onTextChanged(CharSequence ints, start, intbefore, -
int count) { -
-
} -
-
}; -
-
-
private long calculateLength(CharSequence c) { -
double len 0;= -
for ( inti 0;= i < c.length(); i++) { -
int tmp int)= ( c.charAt(i); -
if (tmp 0> && 127)tmp < { -
len += 0.5; -
} else { -
len++; -
} -
} -
return Math.round(len); -
} -
-
-
private void setLeftCount() { -
mTextView.setText(String.valueOf((MAX_COUNT - getInputCount()))); -
} -
-
-
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源码参见:http://download.csdn.net/detail/ace1985/4757626
- Android字数限制的EditText实现方案研究
- Android字数限制的EditText实现方案研究
- Android字数限制的EditText实现方案研究
- Android字数限制的EditText实现方案研究
- Android字数限制的EditText实现方案研究
- Android字数限制的EditText实现方案研究
- Android字数限制的EditText实现方案研究
- Android字数限制的EditText实现方案研究
- Android字数限制的EditText实现方案研究(经典在回贴。)
- Android字数限制的EditText实现
- Android 实现EditText文本的字数限制
- android EditText限制输入字数的方法
- android EditText限制输入的字数
- Android中EditText的输入字数限制
- android的EditText字数检测和限制
- android的EditText字数检测和限制
- Android的EditText字数检测和限制
- Android中限制EditText的最大字数
- S3C2440 FCLK, HCLK, PCLK的关系
- linux 计算时间差
- mysql/hibernate在left join中遇到的问题
- 轻松实现Java与C#时间转换
- Oracle 取随机数
- Android字数限制的EditText实现方案研究
- Android中级教程之----Log图文详解
- 关于SQLite
- 【原创】WP7向Win8移植遇到的问题及独创性解决方案
- 最字头之四:最长不重复字串
- gdb 调试子进程
- dd转换和复制,数据恢复等。
- IE6 浏览器提示
- 选择排序