天天看點

Android 實作自定義自帶删除按鈕的EditText(帶有搜尋接口)一、效果圖:二、實作代碼:

Android 實作自定義自帶删除按鈕的EditText(帶有搜尋接口)

一、效果圖:

Android 實作自定義自帶删除按鈕的EditText(帶有搜尋接口)一、效果圖:二、實作代碼:

二、實作代碼:

MFCleanEditText.java

package cn.zszh.customs.view;

import android.content.Context;
import android.graphics.Canvas;
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.view.View;
import android.view.View.OnTouchListener;
import android.view.View.OnFocusChangeListener;
import android.widget.EditText;
import android.widget.Toast;

/**
 * @說明: 自定義多功能帶删除按鈕的EditText:(可以具有搜尋功能)
 * @author zszh
 *
 */
public class MFCleanEditText extends EditText implements TextWatcher,OnFocusChangeListener{

	private Drawable mClearDrawable;//儲存 EditText右側的删除按鈕    
	private boolean hasFoucs;  //儲存控件是否擷取到焦點
	private OnClickListener mListener;//自定義點選監聽器
	private boolean isFirst=true;//判斷是否是第一次加載

	public MFCleanEditText(Context context) {
		this(context,null);
	}
	public MFCleanEditText(Context context, AttributeSet attrs) {
		//必須使用android.R.attr.editTextStyle,否則失去本有的功能
		this(context, attrs,android.R.attr.editTextStyle);
	}
	public MFCleanEditText(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();//用于設定
	}
	private void init(){
		// 擷取EditText的DrawableRight,假如沒有設定我們就使用預設的圖檔,擷取圖檔的順序是左上右下(0,1,2,3,)
		mClearDrawable = getCompoundDrawables()[2]; //儲存 右側按鈕
		// 預設設定隐藏圖示 
		setClearIconVisible(false); 
		// 設定焦點改變的監聽 
		setOnFocusChangeListener(this); 
		// 設定輸入框裡面内容發生改變的監聽 
		addTextChangedListener(this);
	}
	/** 
	 * @說明:isInnerWidth, isInnerHeight為ture,觸摸點在删除圖示之内,則視為點選了删除圖示 
	 * event.getX() 擷取相對應自身左上角的X坐标 
	 * event.getY() 擷取相對應自身左上角的Y坐标 
	 * getWidth() 擷取控件的寬度 
	 * getHeight() 擷取控件的高度 
	 * getTotalPaddingRight() 擷取删除圖示左邊緣到控件右邊緣的距離 
	 * getPaddingRight() 擷取删除圖示右邊緣到控件右邊緣的距離 
	 * isInnerWidth: 
	 * getWidth() - getTotalPaddingRight() 計算删除圖示左邊緣到控件左邊緣的距離 
	 * getWidth() - getPaddingRight() 計算删除圖示右邊緣到控件左邊緣的距離 
	 * isInnerHeight: 
	 * distance 删除圖示頂部邊緣到控件頂部邊緣的距離 
	 * distance + height 删除圖示底部邊緣到控件頂部邊緣的距離 
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_UP) { 
			int x = (int)event.getX(); 
			int y = (int)event.getY(); 
			if (getCompoundDrawables()[2] != null) { //清除按鈕存在時
				Rect rect = getCompoundDrawables()[2].getBounds(); 
				int height = rect.height(); //按鈕高
				int distance = (getHeight() - height)/2; //按鈕距離上邊緣(下邊緣)的距離
				boolean isInnerWidth = 
						x > (getWidth() - getTotalPaddingRight()) && 
						x < (getWidth() - getPaddingRight()); 
				boolean isInnerHeight = y > distance && y <(distance + height); 
				if (isInnerWidth && isInnerHeight) { 
					this.setText(""); //清除
				} 
			} 
			if(getCompoundDrawables()[0] != null){//左側按鈕存在
				Rect rect = getCompoundDrawables()[0].getBounds();
				int height = rect.height(); //按鈕高
				int distance = (getHeight() - height)/2;  //按鈕距離上邊緣(下邊緣)的距離
				boolean isInnerWidth = 
						x < getTotalPaddingLeft() && 
						x > getPaddingLeft(); 
				boolean isInnerHeight = y > distance && y < (distance + height); 
				if (isInnerWidth && isInnerHeight) { 
					//TODO 左側按鈕被點選
					if(mListener != null){//自定義點選監聽器
						mListener.onClickLeft(getCompoundDrawables()[0]);
					}
				} 
			}
		}
		return super.onTouchEvent(event);
	}


	@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 count, int after) {
		if (hasFoucs) {  
			setClearIconVisible(s.length() > 0);  
		} 
	}
	/** 
	 * 當MFCleanEditText焦點發生變化的時候, 
	 * 輸入長度為零或沒有焦點時,隐藏删除圖示;否則,顯示删除圖示 
	 */  
	@Override
	public void onFocusChange(View v, boolean hasFocus) {
		this.hasFoucs=hasFocus;
		if(hasFocus){
			setClearIconVisible(getText().length()>0);
		}else{
			setClearIconVisible(false);
		}
	}

	protected void setClearIconVisible(boolean visible) { 
		Drawable right = visible ? mClearDrawable : null; 
		setCompoundDrawables(
				getCompoundDrawables()[0], 
				getCompoundDrawables()[1], 
				right, 
				getCompoundDrawables()[3]); 
	}
	public interface OnClickListener {
		void onClickLeft(Object obj);
	}
	public void setOnClickListener(OnClickListener listener){
		mListener=listener;
	}
	@Override
	protected void onDraw(Canvas canvas) {
		if(isFirst){//隻執行一次
			setDrawableBound();
			isFirst=false;
		}
		super.onDraw(canvas);
	}
	/**
	 * 重新設定DrawableLeft、DrawableTop、DrawableRight、DrawableBottom的布局
	 */
	private void setDrawableBound(){
		int padding=getPaddingRight();
		int rectBound=getHeight()-2*padding;
		Rect rect=new Rect();
		if(mClearDrawable!=null){
			rectBound=Math.min(getHeight()-2*padding, mClearDrawable.getIntrinsicWidth());
			rect.set(0, 0, rectBound, rectBound);
			mClearDrawable.setBounds(rect); //右
		}
		Drawable left=getCompoundDrawables()[0];
		Drawable top=getCompoundDrawables()[1];
		Drawable bottom=getCompoundDrawables()[3];
		if(left != null){
			rectBound=Math.min(getHeight()-2*padding, left.getIntrinsicWidth());
			rect.set(0, 0, rectBound, rectBound);
			left.setBounds(rect);
		}
		if(top != null){
			rectBound=Math.min(getHeight()-2*padding, top.getIntrinsicWidth());
			rect.set(0, 0, rectBound, rectBound);
			left.setBounds(rect);
		}
		if(bottom != null){
			rectBound=Math.min(getHeight()-2*padding, bottom.getIntrinsicWidth());
			rect.set(0, 0, rectBound, rectBound);
			left.setBounds(rect);
		}
		setClearIconVisible(getText().length()>0);
	}

}
           
到此,完成自定義自帶删除功能的EditText控件。