android edittext限制字节_EditText输入字数限制的三个方法

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

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

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

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

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

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

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

其实更省事了!

实现吧。

方法一:

布局中限制。

[java] view plaincopy

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

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

(2)字数到,不能输入

方法二:

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

[java] view plaincopy

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

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

(2)字数到,不能输入

方法三:

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

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

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

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

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

[java] view plaincopy

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 

// 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;

}

};

方案二

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

[java] view plaincopy

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 

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,解决方法参考上边方案一

}

}

}

});

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值