1. 程式人生 > >自定義帶清除功能的編輯框---ClearEditText

自定義帶清除功能的編輯框---ClearEditText

簡介

EditText控制元件,對大家來說應該掌握的最基本的控制元件之一。一個app最開始的登入介面,帳號和密碼輸入框就是EditText控制元件,

平時輸入帳號長長的一串,輸入後發現錯了,又要一個一個刪,這時候如果有一個清除功能來清除所有就好了。下面我們就來自

定義這麼一個帶清除功能的編輯框控制元件。

思路

看到這個功能我的第一想法是EditText的不是有個drawableRight屬性來新增有圖示麼,我們可以通過這個來新增清除按鈕啊。

那麼問題來了:

1、清除按鈕什麼時候顯示?又什麼時候隱藏呢?

2、清除按鈕的清除事件怎麼寫呢,可不可以在編輯框的單擊事件(OnClickListener)處理清除按鈕的點選事件呢?

帶著這兩個問題,我們來開始進行編寫

實現

第一個問題,清除按鈕什麼時候顯示,什麼時候隱藏?顯而易見,當編輯框獲得了焦點,且編輯框內容長度大於0的時候才需要

顯示,沒有內容或者編輯框都沒獲取焦點,還顯示個毛是不!所以,理清了前面的思路和問題,我們很容易知道,可以繼承

EditText控制元件來實現,又因為需要獲取焦點且根據內容長度來判斷是否顯示清除按鈕,我們還得實現

OnFocusChangeListener、TextWatcher監聽,啥也不說了,上程式碼:

      //EditText右側的刪除圖示
private Drawable mClearDrawable;
//EditText是否聚焦
private boolean hasFocus;

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

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

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

private void init() {
    mClearDrawable = getCompoundDrawables()[2];//獲取有圖示,0,1,2,3分別代表,左上右下
    if (null == mClearDrawable) {
        mClearDrawable = getResources().getDrawable(R.mipmap.clear);
    }
    mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
    //預設不顯示clear圖示
    setClearIconVisible(false);
    setOnFocusChangeListener(this);
    addTextChangedListener(this);
}

/**
 *  設定清除圖示是否可見
 * @param visible
 */
private void setClearIconVisible(boolean visible) {
    Drawable right = (visible ? mClearDrawable : null);
    setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1],
            right, getCompoundDrawables()[3]);
}


@Override
public void onFocusChange(View v, boolean hasFocus) {
    this.hasFocus = hasFocus;
    if (hasFocus) {
        setClearIconVisible(getText().length() > 0);//獲取焦點且長度大於0時,清除圖示顯示
    } else {
        setClearIconVisible(false);
    }

}

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

}

@Override
public void afterTextChanged(Editable s) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    if (hasFocus) {
        setClearIconVisible(s.length() > 0);//長度改變時,依條件判斷是否顯示圖示
    }
}

如此則實現了符合條件的帶清除按鈕的編輯框,編輯框無內容時,清除圖示不顯示,有焦點且有內容時則顯示。那如果實現點選

清除圖示實現清除功能呢?現在我們來解決第二個問題,清除功能怎麼實現?是否可以通過監聽編輯框單擊事件來實現呢?顯

然,不符合要求,因為我們單擊實現清除功能只針對清除圖示區域,其他區域的單擊不做清除處理,所以不能簡單通過

OnClickListener來進行清除。那麼,要如何實現呢?聰明如我們肯定就知道了,可以通過重寫onTouchEvent事件,當

ACTION_UP動作時,看看當前觸控座標是否在清除圖示區域內,是則進行清除操作,否則不進行!ok,看程式碼:

    @Override
public boolean onTouchEvent(MotionEvent event) {
    if (MotionEvent.ACTION_UP == event.getAction()) {
        if (null != getCompoundDrawables()[2]) {
            int x = (int) event.getX();
            int y = (int) event.getY();
            Rect rect = getCompoundDrawables()[2].getBounds();
            int height = rect.height();//清除圖示高
            int distance = (getHeight() - height) / 2;//清除圖示頂部到控制元件頂部的距離
            boolean w = (x < getWidth() - getPaddingRight()) && (x > getWidth() - getTotalPaddingRight());
            boolean h = (y > distance) && (y < distance + height);
            if (w && h) {
                setText("");
            }
        }
    }
    return super.onTouchEvent(event);
}

好了,至此,帶清除功能的編輯框控制元件,已完全實現,最後的展示效果如下

這裡寫圖片描述