Android带删除功能的EditText在输入信息时很常见,尤其在注册登录界面,其实原理比较简单,根据设置EditText的右边的drawable来进行实现。先来看效果图吧:
删除原理示意图如下:
其原理是当按下图片区域的时对触摸事件进行处理,就是输入的文本清空,就可以达到了删除功能。在onTouchEvent中进行判断触摸位置是否落在:(4) - (3) 与 (4) - (2)之间的距离,即是只要满足条件:
event.getX() > getWidth() - getTotalPaddingRight() && event.getX() < getWidth() - getPaddingRight()
就可以对setText("")进行清空处理。
参考如下:
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.AppCompatEditText;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.lzq.clearedittextdemo.R;
/**
* function: 自定义带清楚功能的EditText
*
*/
@SuppressWarnings("FieldCanBeLocal")
public class ClearEditText extends AppCompatEditText implements View.OnFocusChangeListener{
/** 删除图标 */
private Drawable mClearDrawable;
/** 是否有焦点 */
private boolean mFocus;
public ClearEditText(Context context) {
this(context, null);
}
public ClearEditText(Context context, AttributeSet attrs) {
// 这里构造方法也很重要,不加这个很多属性不能再XML里面定义
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];
//如果EditText右边的删除图标为null则设置默认图标
if (mClearDrawable == null){
mClearDrawable = ContextCompat.getDrawable(getContext(), R.drawable.selector_btn_clear);
}
mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
setClearIconVisible(false);
setOnFocusChangeListener(this);
addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
setClearIconVisible(charSequence.length() > 0);
}
@Override
public void afterTextChanged(Editable editable) {
}
});
}
/** 设置清除按钮是否可见 */
private void setClearIconVisible(boolean visible){
Drawable right = visible ? mClearDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
}
/**
* 如果有焦点并且输入内容长度 > 0 则删除按钮显示,否则隐藏
* @param view EditText
* @param focus 是否聚焦
*/
@Override
public void onFocusChange(View view, boolean focus) {
this.mFocus = focus;
setClearIconVisible(mFocus && getText().length() > 0);
}
/**
* 由于不能直接给EditText设置点击事件,所以可以根据点击的位置来处理点击响应
* (editText的宽度 - 删除图标到控件右边的距离 - 图标宽度) 与 (editText的宽度 - 删除图标到控件右边的距离)之间
* @param event 事件
* @return 事件处理
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP){
if (getCompoundDrawables()[2] != null){
boolean touchable = (event.getX() > getWidth() - getTotalPaddingRight()) && (event.getX() < getWidth() - getPaddingRight());
if (touchable){
setText(""); //清空 相当于点击删除图标清除文字处理
}
}
}
return super.onTouchEvent(event);
}
}