android EditText如何设置输入最大值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一下
            //场景 : plus为非int类型,会导致numberFormatException
            //即使xml文件中设置了digits为0-9,但因为我们在代码中设置了inputFilterValue的过滤器,导致
            //原本digits的digitKeyListener过滤器的优先级在inputFilterValue的后面了,所以用户此时还是可以输入除了digits之外的内容的

            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一下,以为我们如果直接把输入的值toInt的话是会有问题的。

有些同学可能想了,我xml文件中已经设置了digits0-9了啊,为什么toInt还会有问题呢,难道此时ediText还可以输入别的值不成?那我设置的digits岂不是无效了?

这里我们看下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);
}

通过源码我们可以发现,我们再重新设置inputFilter时,系统是会把我们设置的digits重新copy过来的,但这里有个问题就是,digits的优先级被降低了,我们再键盘输入的时候就会导致先执行了我们自定义的inputFilter.这里我们可以看下键盘输入最终对输入内容的处理:

 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();
            }
        }
        ....
}

可以看到这里最后调用的就是我们editText设置的inputFilter,这儿因为我们上面setInputFilter导致digits的优先级变低,所以用户此时输入的内容是没有先受digits的限制的,而是先受限于我们自定义的inputFilter,所以我们在上面的自定义的inputFilterValue中需要try catch一下.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容