Android-->輕松打造帶刪除按鈕的輸入框(EditText),附Emoji表情過濾

輸入框帶刪除按鈕, 此乃標配, 實現(xiàn)起來方法也很多, 網(wǎng)上開源也很多.

但是, 沒事就喜歡瞎折騰.

上圖說話.


這里寫圖片描述
這里寫圖片描述

只是在原生的基礎(chǔ)上加了擴展. 相對來說入侵非常少, 使用方法和原生的一模一樣.無任何閹割.


完整代碼:

public class ExEditText extends AppCompatEditText {

    Rect clearRect = new Rect();

    public ExEditText(Context context) {
        super(context);
    }

    public ExEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ExEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        //在不影響默認過濾規(guī)則的情況下,添加Emoji表情過濾
        if ("emoji".equalsIgnoreCase(String.valueOf(getTag()))) {
            final InputFilter[] filters = getFilters();
            final InputFilter[] newFilters = new InputFilter[filters.length + 1];
            System.arraycopy(filters, 0, newFilters, 0, filters.length);
            newFilters[filters.length] = new EmojiFilter();
            setFilters(newFilters);
        }
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        //焦點改變,檢查是否需要顯示刪除按鈕
        checkEdit(focused);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //用來計算刪除按鈕所在的矩形區(qū)域
        clearRect.set(w - getPaddingRight() - Math.min(w, h), getPaddingTop(), w - getPaddingRight(), Math.min(w, h) - getPaddingBottom());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //檢查點擊刪除按鈕區(qū)域,并且當(dāng)前具有焦點
        if (event.getAction() == MotionEvent.ACTION_DOWN && isFocused()) {
            //檢查是否在刪除按鈕矩形區(qū)域,按下
            if (checkClear(event.getX(), event.getY())) {
                //如果當(dāng)前已經(jīng)是空的, 不處理Touch事件,否則清空文本,達到刪除的效果
                if (!TextUtils.isEmpty(getText())) {
                    setText("");
                    return true;
                }
            }
        }
        return super.onTouchEvent(event);
    }

    private void checkEdit(boolean focused) {
        if (TextUtils.isEmpty(getText()) || !focused) {
            setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
        } else {
            //這里才是關(guān)鍵, 用的是原生的方法顯示刪除圖標.
            setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.base_edit_delete, 0);
        }
    }

    //坐標是否在按鈕區(qū)
    private boolean checkClear(float x, float y) {
        return clearRect.contains(((int) x), (int) y);
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        //時刻檢查一下
        checkEdit(true);
    }
}

Emoji表情過濾:

可能還是有些特殊的Emoji表情,或者字符表情無法過濾, 抱歉;
如果你發(fā)現(xiàn), 請告知, 讓我們一起完善一下, 謝謝!

public class EmojiFilter implements InputFilter {
    Pattern emojiPattern = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
            Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
    private int mMax = -1;//默認不過濾長度

    public EmojiFilter() {
    }

    public EmojiFilter(int max) {
        mMax = max;
    }

    /**
     * 檢測是否有emoji表情
     *
     * @param source
     * @return
     */
    public static boolean containsEmoji(CharSequence source) {
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (!isEmojiCharacter(codePoint)) { //如果不能匹配,則該字符是Emoji表情
                return true;
            }
        }
        return false;
    }

    /**
     * 判斷是否是Emoji
     *
     * @param codePoint 比較的單個字符
     * @return
     */
    private static boolean isEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) ||
                (codePoint == 0xD) || ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
                ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) || ((codePoint >= 0x10000)
                && (codePoint <= 0x10FFFF));
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart,
                               int dend) {
        if (this.emojiPattern.matcher(source).find() || containsEmoji(source)) {
            return "";
        }

        if (mMax != -1) {
            int keep = mMax - (dest.length() - (dend - dstart));
            if (keep <= 0) {
                return "";
            } else if (keep >= end - start) {
                return null; // keep original
            } else {
                keep += start;
                if (Character.isHighSurrogate(source.charAt(keep - 1))) {
                    --keep;
                    if (keep == start) {
                        return "";
                    }
                }
                return source.subSequence(start, keep);
            }
        }

        return source;
    }
}

至此: 文章就結(jié)束了,如有疑問: QQ群 Android:274306954 Swift:399799363 歡迎您的加入.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末苍柏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子潘悼,更是在濱河造成了極大的恐慌,老刑警劉巖糙申,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異疙挺,居然都是意外死亡铐然,警方通過查閱死者的電腦和手機搀暑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來功炮,“玉大人死宣,你說我怎么就攤上這事毅该。” “怎么了潦牛?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巴碗。 經(jīng)常有香客問我,道長橡淆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任逸爵,我火速辦了婚禮构韵,結(jié)果婚禮上瓷胧,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布燃少。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪东跪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天桑驱,我揣著相機與錄音赊级,去河邊找鬼。 笑死兑徘,一個胖子當(dāng)著我的面吹牛崭闲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼暑竟,長吁一口氣:“原來是場噩夢啊……” “哼腹躁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤涂圆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡酒贬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年考蕾,在試婚紗的時候發(fā)現(xiàn)自己被綠了掸鹅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赎瞎。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡态辛,死狀恐怖熟史,靈堂內(nèi)的尸體忽然破棺而出限寞,到底是詐尸還是另有隱情玫霎,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一夯巷、第九天 我趴在偏房一處隱蔽的房頂上張望后雷。 院中可真熱鬧,春花似錦、人聲如沸掰茶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牧嫉。三九已至辽剧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人楼入。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓愧薛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親四濒。 傳聞我的和親對象是個殘疾皇子仆邓,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,526評論 25 707
  • 我自問我最寶貴的財富是什么?_? 自己的身體柜思?父母?兒子定硝?妻子?這些都是寶貴的久信! 但我想說最寶貴的財富應(yīng)該是內(nèi)心的...
    悠然齋主閱讀 370評論 0 1
  • 我的正面管教日記 忙,是我生活的主旋律肿嘲。 誰不忙呢捣作?! 每個生活在城市里的人奋刽,誰不是奮力拼搏雌澄,想要得到更好,成為更...
    江來閱讀 500評論 0 6
  • 周遭是斑斕的,色彩鮮艷钞诡,生機勃勃薄扁。仿佛昨夜的狂風(fēng)暴雨不過是洗凈了萬物身上的塵埃,一切看似在有條不紊中更加美好耳峦。 暴...
    榴蓮?fù)?/span>閱讀 292評論 0 0
  • 數(shù)字編碼記憶法 第六天 10.3 2.利用41-52的數(shù)字編碼記憶「十二生肖」 41子鼠兰粉、42丑牛舔琅、43寅虎流昏、44...
    PP龍青閱讀 1,292評論 1 1