自定義帶清除功能的編輯框---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); }
好了,至此,帶清除功能的編輯框控制元件,已完全實現,最後的展示效果如下