Android之EditText限制6个中文12个英文

来源:互联网 发布:全国地图软件下载 编辑:程序博客网 时间:2024/05/17 05:09

本文只是记录一些零碎的东西

要求输入框最多输入6个中文,12个英文

主要是监听输入框变化

如何使用

EditText.addTextChangedListener(new SketchTextWatcher(mTitleContent));InputFilter[] filters = {new SketchLengthFilter()};EditText.setFilters(filters);

自己处理的两个类:

private static class SketchTextWatcher implements TextWatcher {        private int editStart;        private int editEnd;        private int maxLen = 12; // 6 个汉字 12 个英文字符 (表情 2 个字符)        private EditText editText;        public SketchTextWatcher(EditText e) {            editText = e;        }        @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) {            D.i("slack", "afterTextChanged..." + s);            editStart = editText.getSelectionStart();            editEnd = editText.getSelectionEnd();            // 先去掉监听器,否则会出现栈溢出            editText.removeTextChangedListener(this);            if (!TextUtils.isEmpty(s.toString())) {                while (calculateLength(s.toString()) > maxLen) {                    s.delete(--editStart, editEnd--);                        D.i("slack", "editStart = " + editStart + " editEnd = " + editEnd + " s = " + s);                }            }            editText.setText(s);            editText.setSelection(editStart);            // 恢复监听器            editText.addTextChangedListener(this);        }        /**         * 英文一个字符  中文两个字符         */        private int calculateLength(String string) {            char[] ch = string.toCharArray();            int varlength = 0;            for (char c : ch) {                // changed by zyf 0825 , bug 6918,加入中文标点范围 , TODO 标点范围有待具体化                if ((c >= 0x2E80 && c <= 0xFE4F) || (c >= 0xA13F && c <= 0xAA40) || c >= 0x80) { // 中文字符范围0x4e00 0x9fbb//                    if (c >= 0x4E00 && c <= 0x9FBB) { // 中文字符范围 0x4E00-0x9FA5 + 0x9FA6-0x9FBB                    varlength = varlength + 2;                } else {                    varlength++;                }            }            D.i("slack", "length : " + varlength + " l: " + string.length());            return varlength;        }    }    /**     * 纯英文 纯中文 可以实现 from : http://justwyy.iteye.com/blog/1543419     * 中英混输入 :     * 中文 占 2 位     * 英文 占 1 位     * 思路:计算 已有文字的长度,计算新增文字的长度,长度没有到达限制时,拼接     * 小米 输入时,没有边输入边写入EditText的手机有问题,比如小米     * 华为这种输入一个字符就写入的,没有问题     */    private static class SketchLengthFilter implements InputFilter {        private final int LENGTH_ENGLISH;        SketchLengthFilter() {            this(12);        }        SketchLengthFilter(int english) {            LENGTH_ENGLISH = english;        }        @Override        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {            int keep = LENGTH_ENGLISH - (calculateLength(dest.toString()) - (dend - dstart));            end = calculateLength(source.toString());            D.i("slack", "source("+start+","+end+")="+source+",dest("+dstart+","+dend+")="+dest + " keep:" + keep);            CharSequence result = "";            if(keep >= 0) {                if (keep >= end - start) {                    result = null; // keep original                } else {                    result = subSequence(source.toString(), start, start + keep);                }            }            D.i("slack","result : " + (result == null ? "null": result) + ".");            return result;        }        private CharSequence subSequence(@NonNull String source,int start,int length){            int size = calculateLength(source);            if(size < length){                return source;            }            char[] chars = source.toCharArray();            if(chars.length < length){                return source;            }            char[] result = new char[length - start];            System.arraycopy(chars, start , result, 0, length);            return new String(result);        }        private int calculateLength(String string){            int length = 0;            char[] chars = string.toCharArray();            for (char c : chars) {                if (isChinese(c)) {                    length += 2;                } else {                    length++;                }            }            return length;        }        private boolean isChinese(char c) {            Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);            return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS                    || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS                    || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A                    || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION                    || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION                    || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;        }    }


1 0