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控件。