https://gitee.com/afei_/MyEditText
一 、特點
1.簡單。只有一個不到100行的類,且無任何依賴,也沒有自定義屬性。
2.高效。沒有使用LinearLayout包含EditText+ImageView的組合形式實現,僅僅只有一個繼承EditText的自定義view,減少了佈局的嵌套和view的數量。
3.易用。看我代碼中的調用就知道多簡單了。
二、創建一個ClearEditText類
public class ClearEditText extends EditText implements View.OnFocusChangeListener, TextWatcher {
private Drawable mClearDrawable;
private boolean hasFocus;
public ClearEditText(Context context) {
this(context, null);
}
public ClearEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ClearEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
// getCompoundDrawables() Returns drawables for the left(0), top(1), right(2) and bottom(3)
mClearDrawable = getCompoundDrawables()[2]; // 獲取drawableRight
if (mClearDrawable == null) {
// 如果爲空,即沒有設置drawableRight,則使用R.mipmap.close這張圖片
mClearDrawable = getResources().getDrawable(R.mipmap.close);
}
mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
setOnFocusChangeListener(this);
addTextChangedListener(this);
// 默認隱藏圖標
setDrawableVisible(false);
}
/**
* 我們無法直接給EditText設置點擊事件,只能通過按下的位置來模擬clear點擊事件
* 當我們按下的位置在圖標包括圖標到控件右邊的間距範圍內均算有效
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (getCompoundDrawables()[2] != null) {
int start = getWidth() - getTotalPaddingRight() + getPaddingRight(); // 起始位置
int end = getWidth(); // 結束位置
boolean available = (event.getX() > start) && (event.getX() < end);
if (available) {
this.setText("");
}
}
}
return super.onTouchEvent(event);
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
this.hasFocus = hasFocus;
if (hasFocus && getText().length() > 0) {
setDrawableVisible(true); // 有焦點且有文字時顯示圖標
} else {
setDrawableVisible(false);
}
}
@Override
public void onTextChanged(CharSequence s, int start, int count, int after) {
if (hasFocus) {
setDrawableVisible(s.length() > 0);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
protected void setDrawableVisible(boolean visible) {
Drawable right = visible ? mClearDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
}
}
三、使用
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.afei.myedittext.MainActivity">
<com.afei.myedittext.ClearEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
四、注意事項
1.圖標你可以通過在xml中android:drawableRight=""指定,當然如果你不指定我沒呢就會使用一個默認圖標,這個圖標需要事先準備,畢竟ic_launcher太醜了。
2.圖標默認顯示在右側,如果你的需求很古怪的話可以自己修改相應代碼輕鬆實現(修改getCompoundDrawables()[]對應的數組下標)。
3.DropEditText整個控件的高度不要太小,否則文字或者圖片會顯示不全,這是EditText都會有的問題。
4.例如我的DropEditText使用的高度爲“wrap_content",但是圖片如果較大的話當drawable顯示的時候就會撐高DropEditText的高度,所以你的圖片高度應該適中,我使用的圖片是60*60的,放置在xxhdpi下效果就很好。