安卓禁止輸入中文的簡(jiǎn)單實(shí)現(xiàn)

之前有過(guò)一段時(shí)間,安卓輸入框中禁止輸入中文的實(shí)現(xiàn)方式是自定義一個(gè)TextWatcher耳标,然后在afterTextChanged中判斷是否輸入的是中文邑跪,如果是中文則再做撤銷回滾操作呼猪,也就是做刪掉輸入中文的處理砸琅。不過(guò)感覺(jué)只是為了處理這一個(gè)邏輯就要寫那么多臃腫的代碼,簡(jiǎn)潔性以及可閱讀性不好谚赎,后來(lái)想到了使用InputFilter過(guò)濾的方式诱篷,大大簡(jiǎn)化了代碼,并將該方法公布到工具類當(dāng)中便于其他地方復(fù)用闸盔。

1琳省、使用方法

public static void filterChinese(TextView v) {
    v.setFilters(new InputFilter[]{new InputFilter() {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            if (null != source && isChinese(source.toString())) return "";
            return source;
        }
    }});
}

// 完整的判斷中文漢字和符號(hào)
@SuppressWarnings("unused")
private static boolean isChinese(String strName) {
    char[] ch = strName.toCharArray();
    for (char c : ch) {
        if (isChinese(c)) {
            return true;
        }
    }
    return false;
}

// 根據(jù)Unicode編碼完美的判斷中文漢字和符號(hào)
private static 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.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
            || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
            || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
            || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION;
}

這里思想很簡(jiǎn)單针贬,也就是在輸入過(guò)程中直接過(guò)濾掉中文。

2荡灾、原理解析

對(duì)于想繼續(xù)知道該過(guò)濾原理的同學(xué)瞬铸,這里我直接上一些源碼片段。
這里上下TextView的setFilters方法源碼:

public void setFilters(InputFilter[] filters) {
    if (filters == null) {
        throw new IllegalArgumentException();
    }

    mFilters = filters;

    if (mText instanceof Editable) {
        setFilters((Editable) mText, filters);
    }
}

可以看出荧缘,實(shí)際上操作InputFilter的地方應(yīng)該有兩處拦宣,一處是TextView本身,還有一處是Editable绸罗。

  • 首先看下TextView處理的源碼
private void setText(CharSequence text, BufferType type, boolean notifyBefore, int oldlen) {
    ......
    int n = mFilters.length;
    for (int i = 0; i < n; i++) {
        CharSequence out = mFilters[i].filter(text, 0, text.length(), EMPTY_SPANNED, 0, 0);
        if (out != null) {
            text = out;
        }
    }
    ......
}

代碼很簡(jiǎn)單豆瘫,就是在執(zhí)行了setText時(shí)再執(zhí)行mFilters數(shù)組外驱,從中獲取過(guò)濾掉之后的內(nèi)容腻窒。

  • 然后再分析下Editable
    Editable實(shí)際上只是一個(gè)接口磅崭,這里可以想到的實(shí)際上實(shí)現(xiàn)該接口的是SpannableStringBuilder類,參見(jiàn)實(shí)現(xiàn):
public class SpannableStringBuilder implements CharSequence, GetChars, Spannable, Editable, Appendable, GraphicsOperations

SpannableStringBuilder類主要作用是修改部分字體樣式柔逼,背景顏色等等恩够,這里不做贅述。處理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();
            }
        }
}

可以看出其當(dāng)執(zhí)行內(nèi)容樣式替換過(guò)程中過(guò)濾掉需要過(guò)濾的內(nèi)容儡毕。

好了扑媚,本篇內(nèi)容到此結(jié)束,如果有用到該方法的地方费坊,拿走不謝旬痹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末两残,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子人弓,更是在濱河造成了極大的恐慌崔赌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件县钥,死亡現(xiàn)場(chǎng)離奇詭異慈迈,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)兜看,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門狭瞎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)熊锭,“玉大人,你說(shuō)我怎么就攤上這事碗殷。” “怎么了代乃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵搁吓,是天一觀的道長(zhǎng)吭历。 經(jīng)常有香客問(wèn)我,道長(zhǎng)摩骨,這世上最難降的妖魔是什么朗若? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮唤冈,結(jié)果婚禮上银伟,老公的妹妹穿的比我還像新娘。我一直安慰自己傅物,他們只是感情好琉预,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著卒暂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪昙楚。 梳的紋絲不亂的頭發(fā)上诈嘿,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天奖亚,我揣著相機(jī)與錄音,去河邊找鬼昔字。 笑死,一個(gè)胖子當(dāng)著我的面吹牛作郭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谆扎,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼堂湖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼状土!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起斥季,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤累驮,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后躁锡,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體置侍,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拦焚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年赎败,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蠢甲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峡钓。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡若河,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拉鹃,到底是詐尸還是另有隱情,我是刑警寧澤鲫忍,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布膏燕,位于F島的核電站,受9級(jí)特大地震影響悟民,放射性物質(zhì)發(fā)生泄漏坝辫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一射亏、第九天 我趴在偏房一處隱蔽的房頂上張望近忙。 院中可真熱鬧,春花似錦智润、人聲如沸及舍。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锯玛。三九已至兼蜈,卻和暖如春攘残,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背为狸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工肯腕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钥平。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓实撒,卻偏偏與公主長(zhǎng)得像姊途,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子知态,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容