ClearEditText
import android. content. Context; import android.graphics.drawable.Drawable; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import androidx.appcompat.widget.AppCompatEditText; import com.blankj.utilcode.util.SizeUtils; /** * <pre> * Inherit AppCompatEditText and implement TextWatcher and OnFocusChangeListener * Author: Caowj * Date: 2023/3/22 0022_10:14 *
*/
public class ClearEditText extends AppCompatEditText implements TextWatcher, View.OnFocusChangeListener {
private Drawable mClearDrawable;//clear button image
private boolean hasFocus;
private TextWatcher mTextWatcher;
private OnFocusChangeListener mOnFocusChangeListener;
/**
* Constructor routine operation, not too much explanation here
*/
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() {
hasFocus = hasFocus();
//Get the clear icon, which is set by drawableEnd or drawableRight in the layout file
//getCompoundDrawables: Returns drawables for the left, top, right, and bottom borders.
//getCompoundDrawablesRelative: Returns drawables for the start, top, end, and bottom borders.
mClearDrawable = getCompoundDrawables()[2];
if (mClearDrawable == null) {
mClearDrawable = getCompoundDrawablesRelative()[2];
}
if (mClearDrawable != null) {
//Set the position and size of the icon, getIntrinsicWidth() gets the displayed size instead of the size of the original picture
// mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
mClearDrawable.setBounds(0, 0, SizeUtils.dp2px(26), SizeUtils.dp2px(26));
}
//Default setting to hide the icon
setClearIconVisible(false);
//Set up the listener for focus changes
setOnFocusChangeListener(this);
//Set the listener for content changes in the input box
addTextChangedListener(this);
}
/**
* Simulate a click event by remembering where we pressed
*
* When we press the position at the width of the EditText – the distance from the right side of the text to the left edge of the icon – the distance from the left edge of the icon to the right edge of the control
*
* Even if the icon is clicked between the right edge of the EditText, the vertical direction is bounded by the height of the EditText
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP & amp; & amp; mClearDrawable != null) {
//getTotalPaddingRight() The distance from the left edge of the icon to the right edge of the control
//getCompoundDrawablePadding() indicates the distance from the right side of the text to the left edge of the icon
int left = getWidth() – getTotalPaddingRight() – getCompoundDrawablePadding();
boolean touchable = event.getX() > left & amp; & amp; event.getX() < getWidth();
if (touchable) {
this.setText("");
}
}
return super.onTouchEvent(event);
}
/**
* When the ClearEditText focus changes:
*
* When there is focus and the input text content is not empty, the clear button will be displayed
*/
@Override
public void onFocusChange(View v, boolean hasFocus) {
this.hasFocus = hasFocus;
setClearIconVisible(hasFocus & amp; & amp; !TextUtils.isEmpty(getText()));
if (mOnFocusChangeListener != null) {
mOnFocusChangeListener.onFocusChange(v, hasFocus);
}
}
/**
* When the content in the input box changes:
*
* When there is focus and the input text content is not empty, the clear button will be displayed
*/
@Override
public void onTextChanged(CharSequence s, int start, int count, int after) {
setClearIconVisible(hasFocus & amp; & amp; s. length() > 0);
if (mTextWatcher != null) {
mTextWatcher.onTextChanged(s, start, count, after);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (mTextWatcher != null) {
mTextWatcher.beforeTextChanged(s, start, count, after);
}
}
@Override
public void afterTextChanged(Editable s) {
if (mTextWatcher != null) {
mTextWatcher.afterTextChanged(s);
}
}
/**
* Set the display and hiding of the clear icon, and call setCompoundDrawables to draw it for the EditText
*
* @param visible
*/
protected void setClearIconVisible(boolean visible) {
if (mClearDrawable == null) return;
Drawable right = visible ? mClearDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
}
/**
* 1. If it is itself, call the implementation of the parent class,
*
* 2. If it is set externally, handle the callback by yourself
*/
@Override
public void setOnFocusChangeListener(OnFocusChangeListener l) {
if (l instanceof ClearEditText) {
super.setOnFocusChangeListener(l);
} else {
mOnFocusChangeListener = l;
}
}
@Override
public void addTextChangedListener(TextWatcher watcher) {
if (watcher instanceof ClearEditText) {
super.addTextChangedListener(watcher);
} else {
mTextWatcher = watcher;
}
}
}
use:
<com.test.widgets.ClearEditText android:id="@ + id/edit_sms_code" android:layout_width="wrap_content" android:layout_height="@dimen/dp_94" android:layout_marginLeft="@dimen/dp_80" android:background="@android:color/transparent" android:drawableEnd="@mipmap/ic_delete" android:hint="@string/edit_enter_sms_code_hint" android:imeOptions="actionDone" android:inputType="number" android:maxLength="6" android:text="" android:textColorHint="@color/gray_999" android:textSize="@dimen/sp_28" />