1. 程式人生 > >Android EditText字數限制:中文算2個字元,英文數字算1個字元,超出後彈Toast

Android EditText字數限制:中文算2個字元,英文數字算1個字元,超出後彈Toast

最近有這個需求,在編輯框中輸入字元,有長度的限制,中文算2個字元,英文算1個字元

1、中文、英文、數字都算一個字元:

/**
 * @author pengbo
 * @date 2018/11/12
 * 漢字、英文、數字都算一位,超出位數彈吐司
 */

public class MaxTextNormalLengthFilter implements InputFilter{
    private int mMaxLength;
    private Toast toast;

    public MaxTextNormalLengthFilter(Context context, int maxLen){
        mMaxLength = maxLen;
        toast = Toast.makeText(context, "限"+ maxLen + "個字元!)", Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end,
                               Spanned dest, int dstart , int dend){
        // 判斷是否到達最大長度
        int count = 0;
        // 之前就存在的內容
        int dindex = 0;
        while (count <= mMaxLength && dindex < dest.length()) {
            count++;
            dindex++;
        }
        if (count > mMaxLength) {
            toast.show();
            return dest.subSequence(0, dindex - 1);
        }
        // 從編輯框剛剛輸入進去的內容
        int sindex = 0;
        while (count <= mMaxLength && sindex < source.length()) {
            count++;
            sindex++;
        }
        if (count > mMaxLength) {
            toast.show();
            sindex--;
        }
        return source.subSequence(0, sindex);
    }
}

2、中文算2個字元、英文和數字算1個字元:

/**
 * @author pengbo
 * @date 2018/11/8
 * 數字英文算一位,中文算兩位,超出位數彈吐司
 */
public class MaxTextTwoLengthFilter implements InputFilter {

    private int mMaxLength;
    private Toast toast;

    public MaxTextTwoLengthFilter(Context context, int maxLen){
        mMaxLength = maxLen;
        toast = Toast.makeText(context, "限" + maxLen / 2 + "個漢字或" + maxLen + "個數字英文!)", Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end,
                               Spanned dest, int dstart , int dend){
        // 判斷是否到達最大長度
        int count = 0;
        // 之前就存在的內容
        int dindex = 0;
        while (count <= mMaxLength && dindex < dest.length()) {
            char c = dest.charAt(dindex++);
            if (c < 128) {
                count = count + 1;
            } else {
                count = count + 2;
            }
        }
        if (count > mMaxLength) {
            toast.show();
            return dest.subSequence(0, dindex - 1);
        }
        // 從編輯框剛剛輸入進去的內容
        int sindex = 0;
        while (count <= mMaxLength && sindex < source.length()) {
            char c = source.charAt(sindex++);
            if (c < 128) {
                count = count + 1;
            } else {
                count = count + 2;
            }
        }
        if (count > mMaxLength) {
            toast.show();
            sindex--;
        }
        return source.subSequence(0, sindex);
    }
}

3、如果有那種輸入大量篇幅的,肯定有一個字數的提示,或者在編輯框中輸入了內容之後需要回調:

/**
 * @author pengbo
 * @date 2018/11/12
 * EditText新增文字限制的時候使用此TextWatcher,
 * 提供回撥,有部分介面使用到判斷
 */

public class MaxEditTextWatcher implements TextWatcher {
    /** 都算一位或 中文算兩位 */
    public static final int ALL_ONE = 0;
    public static final int CHINESE_TWO = 1;
    private int mType;
    private int mMaxLen;
    private Context mContext;
    private EditText etText;
    private TextView tvByteLimit;
    private TextChangedCallBack mCallBack;

    public MaxEditTextWatcher(int type, int maxlen, Context context,  EditText editText) {
        this(type, maxlen, context, editText, null);
    }

    public MaxEditTextWatcher(int type, int maxLen, Context context, EditText editText, TextView textView) {
       this(type, maxLen, context, editText, textView, null);
    }

    public MaxEditTextWatcher(int type,int maxLen, Context context, EditText editText, TextView textView,
                              TextChangedCallBack callBack) {
        mType = type;
        mMaxLen = maxLen;
        mContext = context;
        etText = editText;
        tvByteLimit = textView;
        mCallBack = callBack;
        if (mType == ALL_ONE) {
            etText.setFilters(new InputFilter[]{new MaxTextNormalLengthFilter(mContext, mMaxLen)});
        } else if (mType == CHINESE_TWO){
            etText.setFilters(new InputFilter[]{new MaxTextTwoLengthFilter(mContext, mMaxLen)});
        }
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        if (tvByteLimit != null) {
            if (mType == ALL_ONE) {
                int length = etText.getText().length();
                tvByteLimit.setText(length + "/" + mMaxLen);
            } else if (mType == CHINESE_TWO) {
                int length = CommonUtil.judgeTextLength(etText.getText().toString());
                tvByteLimit.setText(length + "/" + mMaxLen);
            }
        }

        if (mCallBack != null) {
            mCallBack.changed(editable);
        }
    }

    public interface TextChangedCallBack {
        void changed(Editable editable);
    }
}

CommonUtil:

  /**
     * 返回text的長度,一個漢字算兩個,數字和英文算一個
     * @param text
     * @return
     */
    public static int judgeTextLength(String text) {
        if (TextUtils.isEmpty(text)) {
            return 0;
        }
        int count = 0;
        for (int i = 0; i < text.length(); i++) {
            char item = text.charAt(i);
            if (item < 128) {
                count++;
            } else {
                count += 2;
            }
        }
        return count;
    }