EditText 字符长度限制 - 中文(全角字符)占两个字符位

需求

  • 对输入框输入字符做字符长度限制
  • 汉字占两个字符,字母占一个字符

结果

  • 汉字(根据字符实际占用字节获得,另含大量特殊字符)占两个字符,字母(根据字符实际占用字节获得,另含大量特殊字符)占一个字符
  • 在预期不超长时正常输入,在预期超长时截取新输入字符首端最大长度拼接(词组、粘贴、复制、联想等),在已超长时无法输入

实现

  • 自定义输入拦截器
/**
 * EditText 字符长度限制(字母一个字符,汉字两个字符)
 *
 * @author gavin.xiong 2017/7/12
 */
public class LengthFilter implements InputFilter {

    private final int MAX_EN; // 最大英文/数字长度 一个汉字算两个字母

    public LengthFilter(int MAX_EN) {
        this.MAX_EN = MAX_EN;
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {

        // 新输入的字符串为空直接不接收(删除剪切等)
        if (TextUtils.isEmpty(source)) return "";

        // 输入前就存在的字符长度
        int destCount = getCount(dest.toString());

        // 输入前就已满直接不接收
        if (destCount >= MAX_EN) return "";

        // 新输入的字符长度
        int sourceCount = getCount(source.toString());

        // 如果拼接后不超长,直接拼接
        if (destCount + sourceCount <= MAX_EN) return source;

        // 超长时不应该直接拒绝,应在允许范围内尽量拼接
        return getByCount(source.toString(), MAX_EN - destCount);
    }

    /**
     * 超长时根据剩余长度在字符范围内截取字符串
     */
    private String getByCount(String s, int count) {
        String temp = "";
        int tempCount = 0;

        char[] cs = s.toCharArray();
        for (char c : cs) {
            if (tempCount + getCount(c) <= count) {
                tempCount += getCount(c);
                temp += c;
            } else {
                break;
            }
        }

        return temp;
    }

    /**
     * 计算字符串长度
     */
    private int getCount(String s) {
        if (TextUtils.isEmpty(s)) {
            return 0;
        }

        int count = 0;
        char[] cs = s.toCharArray();
        for (char c : cs) {
            count += getCount(c);
        }

        return count;
    }

    /**
     * 单字符占位判定
     */
    private int getCount(char c) {
        return String.valueOf(c).getBytes().length > 2 ? 2 : 1;
    }
}
  • 使用
editText.setFilters(new InputFilter[]{new LengthFilter(20)});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 我们在将来不久后相爱 我们是沙子里滚石 相遇过后就各自崩溃 一颗一颗的崩子,被装在薯片袋里 我们在遇见爱情时, 随...
    梁伯益阅读 115评论 2 7
  • 一年有52周,每周来尝试一个小小的改变吧~然后让我们去坚持那些有用的,丢掉没有的,相信一定会让我们的生活更加简单、...
    机智果阅读 1,929评论 0 1
  • 4.“小笼包”好的标准备是什么?【识别概括技术】 1.结构思考力的第一层:理解里的“识别概括技术” 引出案例:好的...
    央曰阅读 1,097评论 1 3