android EditText如何設(shè)置輸入最大值inputFilter

/**
 * 輸入最大值限制
 */
class InputFilterValue(var context: Context, private var mMax: Int, var showToast: Boolean = true, var toast: String = "最大可輸入${mMax}") : InputFilter {
    override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence? {
        val plus = dest.toString().plus(source)
        if (TextUtils.isEmpty(plus)) return null
        return try {

            //mother fucker 這里要try catch一下
            //場(chǎng)景 : plus為非int類型,會(huì)導(dǎo)致numberFormatException
            //即使xml文件中設(shè)置了digits為0-9,但因?yàn)槲覀冊(cè)诖a中設(shè)置了inputFilterValue的過(guò)濾器,導(dǎo)致
            //原本digits的digitKeyListener過(guò)濾器的優(yōu)先級(jí)在inputFilterValue的后面了,所以用戶此時(shí)還是可以輸入除了digits之外的內(nèi)容的

            when {
                plus.toInt() > mMax -> {
                    if (showToast) ToastUtil.showCenter(context, toast)
                    ""
                }
                else -> null
            }
        } catch (e: NumberFormatException) {
            null
        }
    }
}

使用

 InputFilter[] filters = editText.getFilters();
 InputFilter[] newFilters = new InputFilter[filters.length + 1];
 System.arraycopy(filters, 0, newFilters, 0, filters.length);
 newFilters[filters.length] = new InputFilterValue(...)
 editText.setFilters(newFilters);

這里要注意的是,我們需要在自定義的inputFilter中try catch一下,以為我們?nèi)绻苯影演斎氲闹?code>toInt的話是會(huì)有問(wèn)題的。

有些同學(xué)可能想了,我xml文件中已經(jīng)設(shè)置了digits0-9了啊,為什么toInt還會(huì)有問(wèn)題呢,難道此時(shí)ediText還可以輸入別的值不成?那我設(shè)置的digits豈不是無(wú)效了?

這里我們看下editText.setFilters(newFilters)的源碼處理:

public void setFilters(InputFilter[] filters) {
    if (filters == null) {
        throw new IllegalArgumentException();
    }
    mFilters = filters;
    if (mText instanceof Editable) {
        setFilters((Editable) mText, filters);
    }
}

private void setFilters(Editable e, InputFilter[] filters) {
    if (mEditor != null) {
        final boolean undoFilter = mEditor.mUndoInputFilter != null;
        final boolean keyFilter = mEditor.mKeyListener instanceof InputFilter; 
        int num = 0;
        if (undoFilter) num++;
        if (keyFilter) num++;
        if (num > 0) {
            InputFilter[] nf = new InputFilter[filters.length + num];
            System.arraycopy(filters, 0, nf, 0, filters.length);
            num = 0;
            if (undoFilter) {
                nf[filters.length] = mEditor.mUndoInputFilter;
                num++;
            }

            if (keyFilter) {
                nf[filters.length + num] = (InputFilter) mEditor.mKeyListener;
            } 
            e.setFilters(nf);
            return;
        }
    }
    e.setFilters(filters);
}

通過(guò)源碼我們可以發(fā)現(xiàn),我們?cè)僦匦略O(shè)置inputFilter時(shí),系統(tǒng)是會(huì)把我們?cè)O(shè)置的digits重新copy過(guò)來(lái)的,但這里有個(gè)問(wèn)題就是,digits的優(yōu)先級(jí)被降低了,我們?cè)冁I盤輸入的時(shí)候就會(huì)導(dǎo)致先執(zhí)行了我們自定義的inputFilter.這里我們可以看下鍵盤輸入最終對(duì)輸入內(nèi)容的處理:

 public SpannableStringBuilder replace(final int start, final int end,
            CharSequence tb, int tbstart, int tbend) {
        checkRange("replace", start, end);

        int filtercount = mFilters.length;
        for (int i = 0; i < filtercount; i++) {
            CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end);

            if (repl != null) {
                tb = repl;
                tbstart = 0;
                tbend = repl.length();
            }
        }
        ....
}

可以看到這里最后調(diào)用的就是我們editText設(shè)置的inputFilter,這兒因?yàn)槲覀兩厦?code>setInputFilter導(dǎo)致digits的優(yōu)先級(jí)變低,所以用戶此時(shí)輸入的內(nèi)容是沒有先受digits的限制的,而是先受限于我們自定義的inputFilter,所以我們?cè)谏厦娴淖远x的inputFilterValue中需要try catch一下.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容