[Android]自訂帶刪除輸入框
在項目開發中,帶刪除按鈕輸入框也是人們常常用到的,該文章便介紹一下如何建立一個帶刪除輸入框。其中,需要解決的問題如下:
a)建立自訂editText類
b)在自訂editText中顯示刪除圖片
c)根據輸入框的輸入情況顯示或隱藏圖片
d)點擊刪除圖片文字消失,圖片隱藏
e)根據輸入框焦點失去和獲得狀態顯示或隱藏圖片
好了,問題明確了,開始實現功能:
a)建立一個名為MyClearEditText的class檔案,並整合EditText,實現其構造方法:
public MyClearEditText(Context context) {this(context, null);// TODO Auto-generated constructor stub}public MyClearEditText(Context context, AttributeSet attrs) {this(context, attrs, android.R.attr.editTextStyle);// TODO Auto-generated constructor stub}public MyClearEditText(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}ok,第一個問題解決了,進入第二步。
b)在editText中,我們若想顯示上下左右方向的圖片,有著setCompoundDrawables或setCompoundDrawablesWithIntrinsicBounds方法,具體的話,可以去百度一下其區別,在這裡,我使用的是setCompoundDrawablesWithIntrinsicBounds方法。代碼如下:
/** * 初始化清除的圖片 */private void initClearDrawable() {draw = getCompoundDrawables()[2];// 判斷清除的圖片是否為空白if (draw == null) {draw = getResources().getDrawable(R.drawable.editdelete);}// 為輸入框設定圖片this.setCompoundDrawablesWithIntrinsicBounds(null, null, draw, null);}思路為:先找到editText中右邊的圖片,若為null,則為其設定預設圖片,然後再為輸入框顯示圖片,便獲得效果:
c)需要獲得輸入框的情況,便要實現TextWatcher介面。
監聽:
this.addTextChangedListener(this);
需要實現的方法:
public void onTextChanged(CharSequence text, int start, int lengthBefore,int lengthAfter) {// 判斷輸入框中是否有內容if (text.length() > 0) {this.setCompoundDrawablesWithIntrinsicBounds(null, null, draw, null);} else {this.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);}}public void beforeTextChanged(CharSequence s, int start, int count,int after) {// TODO Auto-generated method stub}public void afterTextChanged(Editable s) {// TODO Auto-generated method stub}
d)怎麼監聽是點擊到那個刪除圖片的呢,這是一個值得思考的問題,在這裡,有一種解決方案,那便是觸點監聽,根據點擊的位置來判斷是否在圖片所處位置的範圍內:
@Overridepublic boolean onTouchEvent(MotionEvent event) {// 判斷觸碰是否結束if (event.getAction() == MotionEvent.ACTION_UP) {// 判斷所觸碰的位置是否為清除的按鈕if (event.getX() > (getWidth() - getTotalPaddingRight())&& event.getX() < (getWidth() - getPaddingRight())) {// 將editText裡面的內容清除setText();}}return super.onTouchEvent(event);}
實現以上步驟後,大致的自訂刪除輸入框功能便可以實現了,但是還是有些問題,假如有兩個輸入框,當向其中一個輸入框輸入文字後,點擊另外一個輸入框,上一個輸入框還是會顯示刪除圖片,解決方案如下:
e)既然是根據焦點的得失來判斷,當然是實現焦點監聽的方法:
@Overrideprotected void onFocusChanged(boolean focused, int direction,Rect previouslyFocusedRect) {// TODO Auto-generated method stubsuper.onFocusChanged(focused, direction, previouslyFocusedRect);// 判斷焦點失去和得到時的操作if (focused && !this.getText().toString().equals()) {this.setCompoundDrawablesWithIntrinsicBounds(null, null, draw, null);} else {this.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);}}
ok,完整版的自訂帶刪除輸入框就完全實現了。為方便大家學習,以下為完整代碼:
package com.xiaoyan.xiaoyanlibrary.common.widget.edittext;import com.xiaoyan.xiaoyanlibrary.R;import android.content.Context;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.text.Editable;import android.text.TextWatcher;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.EditText;/** * 自訂一個具有清除功能的editText * * @author xiejinxiong * */public class MyClearEditText extends EditText implements TextWatcher {/** 儲存清除的圖片 */private Drawable draw;public MyClearEditText(Context context) {this(context, null);// TODO Auto-generated constructor stub}public MyClearEditText(Context context, AttributeSet attrs) {this(context, attrs, android.R.attr.editTextStyle);// TODO Auto-generated constructor stub}public MyClearEditText(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initClearDrawable();this.addTextChangedListener(this);}@Overrideprotected void onFocusChanged(boolean focused, int direction,Rect previouslyFocusedRect) {// TODO Auto-generated method stubsuper.onFocusChanged(focused, direction, previouslyFocusedRect);// 判斷焦點失去和得到時的操作if (focused && !this.getText().toString().equals()) {this.setCompoundDrawablesWithIntrinsicBounds(null, null, draw, null);} else {this.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);}}/** * 初始化清除的圖片 */private void initClearDrawable() {draw = getCompoundDrawables()[2];// 判斷清除的圖片是否為空白if (draw == null) {draw = getResources().getDrawable(R.drawable.editdelete);}// 將輸入框預設設定為沒有清除的按鈕this.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);}public void onTextChanged(CharSequence text, int start, int lengthBefore,int lengthAfter) {// 判斷輸入框中是否有內容if (text.length() > 0) {this.setCompoundDrawablesWithIntrinsicBounds(null, null, draw, null);} else {this.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);}}public void beforeTextChanged(CharSequence s, int start, int count,int after) {// TODO Auto-generated method stub}public void afterTextChanged(Editable s) {// TODO Auto-generated method stub}@Overridepublic boolean onTouchEvent(MotionEvent event) {// 判斷觸碰是否結束if (event.getAction() == MotionEvent.ACTION_UP) {// 判斷所觸碰的位置是否為清除的按鈕if (event.getX() > (getWidth() - getTotalPaddingRight())&& event.getX() < (getWidth() - getPaddingRight())) {// 將editText裡面的內容清除setText();}}return super.onTouchEvent(event);}}