Android 自定義ClearEditTextView

ClearEditTextView通過擴(kuò)展EditText漱抓,添加了右邊清除按鈕缺前、輸入數(shù)據(jù)不合法時(shí)可左右抖動(dòng)的功能会放。效果如下:


模擬登錄

整體的實(shí)現(xiàn)代碼如下:

public class ClearEditTextView extends EditText implements View.OnFocusChangeListener, TextWatcher {

    //右邊的刪除按鈕
    private Drawable mClearDrawable;

    public ClearEditTextView(Context context) {
        this(context, null);
    }

    public ClearEditTextView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.editTextStyle);
    }

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

    private void init() {
        mClearDrawable = getResources().getDrawable(R.drawable.clear);
        //設(shè)置刪除按鈕的邊界
        mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
        //默認(rèn)隱藏刪除按鈕
        setClearIcon(false);

        //監(jiān)聽EditText焦點(diǎn)變化盖腿,以根據(jù)text長(zhǎng)度控制刪除按鈕的顯示、隱藏
        setOnFocusChangeListener(this);
        //監(jiān)聽文本內(nèi)容變化
        addTextChangedListener(this);
    }

    /**
     * 控制EditText右邊制刪除按鈕的顯示愈捅、隱藏
     */
    private void setClearIcon(boolean isShow) {
        Drawable rightDrawable = isShow ? mClearDrawable : null;
        setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1],
                rightDrawable, getCompoundDrawables()[3]);
    }

    /**
     * 有焦點(diǎn)遏考,并文本長(zhǎng)度大于0則顯示刪除按鈕
     *
     * @param v
     * @param hasFocus
     */
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            setClearIcon(getText().length() > 0);
        } else {
            setClearIcon(false);
        }
    }

    /**
     * 文本內(nèi)容變化時(shí)回調(diào)
     * 當(dāng)文本長(zhǎng)度大于0時(shí)顯示刪除按鈕, 否則隱藏
     *
     * @param text
     * @param start
     * @param lengthBefore
     * @param lengthAfter
     */
    @Override
    public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        setClearIcon(text.length() > 0);
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void afterTextChanged(Editable s) {

    }

    /**
     * 通過手指的觸摸位置模式刪除按鈕的點(diǎn)擊事件
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (getCompoundDrawables()[2] != null) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                boolean xTouchable = event.getX() > (getWidth() - getPaddingRight() - mClearDrawable.getIntrinsicWidth())
                        && (event.getX() < (getWidth() - getPaddingRight()));

                boolean yTouchable = event.getY() > (getHeight() - mClearDrawable.getIntrinsicHeight()) / 2
                        && event.getY() < (getHeight() + mClearDrawable.getIntrinsicHeight()) / 2;

                //清除文本
                if (xTouchable && yTouchable) {
                    setText("");
                }
            }
        }
        return super.onTouchEvent(event);
    }


    /**
     * EditText抖動(dòng)
     *
     * @param counts
     * @return
     */
    public void startShake(int counts) {
        Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
        translateAnimation.setInterpolator(new CycleInterpolator(counts));
        translateAnimation.setDuration(500);
        startAnimation(translateAnimation);
    }
}

大致說一下流程蓝谨,首先給EditText添加addTextChangedListener來監(jiān)聽輸入文本的變化灌具,如果EditText有焦點(diǎn)并文本長(zhǎng)度大于0則將EditText的drawableRight設(shè)置為刪除的圖片否則設(shè)置為空:

@Override
    public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        setClearIcon(text.length() > 0);
    }
private void setClearIcon(boolean isShow) {
        Drawable rightDrawable = isShow ? mClearDrawable : null;
        setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1],
                rightDrawable, getCompoundDrawables()[3]);
    }

這樣刪除按鈕就添加好了。由于不能直接給添加的刪除按鈕綁定點(diǎn)擊事件譬巫,所以可以考慮通過重寫EditText的onTouchEvent方法稽亏,如果手指的觸摸x、y坐標(biāo)在刪除圖片上則執(zhí)行刪除操作:

@Override
    public boolean onTouchEvent(MotionEvent event) {
        if (getCompoundDrawables()[2] != null) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                boolean xTouchable = event.getX() > (getWidth() - getPaddingRight() - mClearDrawable.getIntrinsicWidth())
                        && (event.getX() < (getWidth() - getPaddingRight()));

                boolean yTouchable = event.getY() > (getHeight() - mClearDrawable.getIntrinsicHeight()) / 2
                        && event.getY() < (getHeight() + mClearDrawable.getIntrinsicHeight()) / 2;

                //清除文本
                if (xTouchable && yTouchable) {
                    setText("");
                }
            }
        }
        return super.onTouchEvent(event);
    }

到這里刪除按鈕的邏輯就完成了缕题。關(guān)于左右抖動(dòng)的效果就是給EditText設(shè)置一個(gè)左右移動(dòng)的動(dòng)畫:

public void startShake(int counts) {
        Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
        translateAnimation.setInterpolator(new CycleInterpolator(counts));
        translateAnimation.setDuration(500);
        startAnimation(translateAnimation);
    }

到這里一個(gè)簡(jiǎn)單的EditText擴(kuò)展就實(shí)現(xiàn)了截歉。

關(guān)于倒計(jì)時(shí)的功能可通過CountDownTimer類方便的實(shí)現(xiàn):

mCountDownTimer = new CountDownTimer(long millisInFuture, long countDownInterval) {
            @Override
            public void onTick(long millisUntilFinished) {
               //倒計(jì)時(shí)進(jìn)行中
            }

            @Override
            public void onFinish() {
               //倒計(jì)時(shí)結(jié)束
            }
        }

參數(shù)millisInFuture代表倒計(jì)時(shí)的總時(shí)長(zhǎng),countDownInterval代表時(shí)間間隔烟零,單位都是毫秒瘪松。通過CountDownTimer類的start()cancel()方法可以開始和結(jié)束倒計(jì)時(shí)。

demo下載...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末锨阿,一起剝皮案震驚了整個(gè)濱河市宵睦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌墅诡,老刑警劉巖壳嚎,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡烟馅,警方通過查閱死者的電腦和手機(jī)说庭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來郑趁,“玉大人刊驴,你說我怎么就攤上這事」讶螅” “怎么了捆憎?”我有些...
    開封第一講書人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)梭纹。 經(jīng)常有香客問我躲惰,道長(zhǎng),這世上最難降的妖魔是什么变抽? 我笑而不...
    開封第一講書人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任礁扮,我火速辦了婚禮,結(jié)果婚禮上瞬沦,老公的妹妹穿的比我還像新娘。我一直安慰自己雇锡,他們只是感情好逛钻,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著锰提,像睡著了一般曙痘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上立肘,一...
    開封第一講書人閱讀 52,337評(píng)論 1 310
  • 那天边坤,我揣著相機(jī)與錄音,去河邊找鬼谅年。 笑死茧痒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的融蹂。 我是一名探鬼主播旺订,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼超燃!你這毒婦竟也來了区拳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤意乓,失蹤者是張志新(化名)和其女友劉穎樱调,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡笆凌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年圣猎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片菩颖。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡样漆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晦闰,到底是詐尸還是另有隱情放祟,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布呻右,位于F島的核電站跪妥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏声滥。R本人自食惡果不足惜眉撵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望落塑。 院中可真熱鬧纽疟,春花似錦、人聲如沸憾赁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽龙考。三九已至蟆肆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晦款,已是汗流浹背炎功。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缓溅,地道東北人蛇损。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像坛怪,于是被迫代替她去往敵國(guó)和親州藕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359

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

  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 46,791評(píng)論 22 665
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程酝陈,因...
    小菜c閱讀 6,444評(píng)論 0 17
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,302評(píng)論 25 707
  • 大概用了4天左右的時(shí)間床玻、讀了《結(jié)網(wǎng)》。整本書看下來沉帮、并沒有在思維上得到太深刻的提高--或許是時(shí)間太短锈死、看得太快贫堰、也...
    sanduck閱讀 155評(píng)論 0 0
  • 旋轉(zhuǎn)木馬價(jià)格多少錢?鄭州金寶游樂設(shè)備有限公司生產(chǎn)的旋轉(zhuǎn)木馬價(jià)格在2萬到6萬之間待牵,其中囊括了簡(jiǎn)易轉(zhuǎn)馬其屏、單飛檐轉(zhuǎn)馬、雙...
    金寶客服王慶科閱讀 242評(píng)論 0 0