EditText限制中文字符长度

        EditText文本输入框,非常常见的一个控件。在使用时常常会限制用户输入的长度,一般来说直接在xml里面设置android:maxlength即可。但有时候有些场景,比如输入名称,可以输入中文和字母,但是中文算两个字符长度,这时设置maxlength可能就不太符合我们的需求了。为了让用户输入足够的字符后不允许输入,就需要使用TextWatcher来对输入进行控制。具体代码如下

/**
 * 限定输入名称长度(中文算两个长)
 */

public class NameWatcher implements TextWatcher {

    private int maxLength = 10;
    private EditText mEditText;

    public NameWatcher(EditText editText, int maxLength) {
        this.mEditText = editText;
        this.maxLength = maxLength;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    /**
     * @param s      editText设置的值
     * @param start  光标从哪里开始输入
     * @param before
     * @param count  此次输入的字符长度
     */
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        int totalLength = getWordCount(s.toString());
        if (totalLength > maxLength) {
            //当前输入的字符
            CharSequence input = s.subSequence(start, start + count);
            int inputLength = getWordCount(input.toString());
            //有效字符
            String valid = getLimitString(input, maxLength - (totalLength - inputLength));
            if (start + count == s.length()) {
                //在最末尾添加的字符
                mEditText.setText(String.valueOf(s.subSequence(0, start) + valid));
                mEditText.setSelection(mEditText.getText().length());
            } else {
                //在中间添加的
                mEditText.setText(String.valueOf(s.subSequence(0, start)
                        + valid
                        + String.valueOf(s.subSequence(start + count, s.length()))));
                mEditText.setSelection(start + valid.length());
            }
        }
    }

    @Override
    public void afterTextChanged(Editable s) {

    }

    /**
     * 获取字符串长度
     * 由于Java是基于Unicode编码的,因此,一个汉字的长度为1,而不是2。
     * 要以字节单位获得字符串的长度。
     * 例如,“123abc长城”按字节长度计算是10,而按Unicode计算长度是8。为了获得10,
     * 需要从头扫描根据字符的Ascii来获得具体的长度。如果是标准的字符,Ascii的范围是0至255
     * ,如果是汉字或其他全角字符,Ascii会大于255。
     *
     * @param s
     * @return
     */
    public int getWordCount(String s) {
        int length = 0;
        for (int i = 0; i < s.length(); i++) {
            int ascii = Character.codePointAt(s, i);
            if (ascii >= 0 && ascii <= 255)
                length++;
            else
                length += 2;

        }
        return length;
    }

    /**
     * 限制长度的字符
     *
     * @param str
     * @param maxLength
     * @return
     */
    private String getLimitString(CharSequence str, int maxLength) {
        int length = 0;
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            int ascii = Character.codePointAt(str, i);
            if (ascii >= 0 && ascii <= 255) {
                if (length < maxLength) {
                    length++;
                    stringBuilder.append(str.charAt(i));
                } else {
                    return stringBuilder.toString();
                }
            } else {
                if (length + 2 <= maxLength) {
                    length += 2;
                    stringBuilder.append(str.charAt(i));
                } else {
                    return stringBuilder.toString();
                }
            }
        }
        return stringBuilder.toString();
    }
}

使用:

mEtName.addTextChangedListener(new NameWatcher(mEtName, 20));

 顺带记录一下,inputType设置为“number”的话是不允许输入空格的,而设置为“phone”则可以输入空格。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值