自定義控件:帶有清除功能的 ClearEditText

這裏寫圖片描述

實現點擊“刪除”按鈕,會清空EditText

基本實現

首先給給EditText設置drawableRight屬性

<EditText
    ...
    android:drawableRight="@drawable/edittext_delete"
    android:paddingRight="50dp"
    android:paddingRight="50dp"
    ...
/>

android:paddingRight 設置刪除按鈕到右邊距。

那麼怎麼判斷你點擊的是 “刪除”,而不是EditText?答案是根據點擊的x座標來判斷。

OnTouchListener()監聽中判斷drawableRight是否存在,不存在,不作處理。判斷手勢的action,只有手指離開屏幕的時候才清空EditText。

editText.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        //如果drawableRight==null,就不做處理。
        Drawable[] drawables = et2.getCompoundDrawables();
        Drawable drawableRight = drawables[2];
        if (drawableRight == null) {
            return false;
        }

        //只有手指離開屏幕的時候才清空EditText
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (event.getX() > (et2.getWidth() - et2.getPaddingRight() - drawableRight.getIntrinsicWidth())) {
                et2.setText("");
            }
        }
        return false;
    }
});

完善

但是上面的有個缺點,由於設置了drawableRight,“刪除”圖標會一直存在。怎麼實現“當輸入的文字長度>0時,才顯示刪除按鈕,文字長度=0時,不顯示刪除按鈕 。” 這樣的話,xml中就不能給EditText設置屬性drawableRight了,需要動態的設置。也就是說:當輸入的文字長度>0時,添加drawableRight屬性,文字長度=0時,drawableRight屬性爲null 。

先獲取drawableRight圖片。
注意setBounds(...)方法一定要調用,否則setCompoundDrawables()無效,刪除圖片不顯示。

Drawable[] drawables = et2.getCompoundDrawables();
et2.setCompoundDrawables(drawables[0], drawables[1], null, drawables[3]);

if (null == drawable2) {
    drawable2 = getResources().getDrawable(R.drawable.edittext_delete);
}
drawable2.setBounds(0, 0, drawable2.getIntrinsicWidth(), drawable2.getIntrinsicHeight());

再判斷輸入內容的長度

et2.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (s.length() > 0) {
            setClearVisible(true);
        } else {
            setClearVisible(false);
        }
    }

    @Override
    public void afterTextChanged(Editable s) {

    }
});

setClearVisible(boolean visible)

public void setClearVisible(boolean visible) {
    Drawable drawableRight = visible ? drawable2 : null;
    Drawable[] drawables = et2.getCompoundDrawables();
    et2.setCompoundDrawables(drawables[0], drawables[1], drawableRight, drawables[3]);
}

還有的還需要設置,發現不設置也可以。

et2.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            if (et2.getText().length() > 0) {
                setClearVisible(true);
            } else {
                setClearVisible(false);
            }
        }
    }
});

類ClearEditText

Demo: https://git.oschina.net/customView/ClearEditText.git

public class ClearEditText extends AppCompatEditText implements OnFocusChangeListener, TextWatcher {
    /**
     * 刪除按鈕的引用
     */
    Drawable mClearDrawable;
    /**
     * 控件是否有焦點
     */
    private boolean hasFoucs;

    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 defStyle) {
        super(context, attrs, defStyle);
        init();
    }


    private void init() {
        //獲取EditText的DrawableRight,假如沒有設置我們就使用默認的圖片
        mClearDrawable = getCompoundDrawables()[2];
        if (mClearDrawable == null) {
            //          throw new NullPointerException("You can add drawableRight attribute in XML");
            mClearDrawable = getResources().getDrawable(R.drawable.edittext_delete);
        }

        mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
        setPadding(12, getPaddingTop(), 12, getPaddingBottom());
        //默認設置隱藏圖標
        setClearIconVisible(false);
        //設置焦點改變的監聽
        setOnFocusChangeListener(this);
        //設置輸入框裏面內容發生改變的監聽
        addTextChangedListener(this);
    }


    @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) {
                    this.setText("");
                }
            }
        }

        return super.onTouchEvent(event);
    }

    /**
     * 當ClearEditText焦點發生變化的時候,判斷裏面字符串長度設置清除圖標的顯示與隱藏
     */
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        this.hasFoucs = hasFocus;
        if (hasFocus) {
            setClearIconVisible(getText().length() > 0);
        } else {
            setClearIconVisible(false);
        }
    }


    /**
     * 設置清除圖標的顯示與隱藏,調用setCompoundDrawables爲EditText繪製上去
     *
     * @param visible
     */
    protected void setClearIconVisible(boolean visible) {
        Drawable right = visible ? mClearDrawable : null;
        setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
    }


    /**
     * 當輸入框裏面內容發生變化的時候回調的方法
     */
    @Override
    public void onTextChanged(CharSequence s, int start, int count,
                              int after) {
        if (hasFoucs) {
            setClearIconVisible(s.length() > 0);
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
                                  int after) {

    }

    @Override
    public void afterTextChanged(Editable s) {

    }


    /**
     * 設置晃動動畫
     */
    public void setShakeAnimation() {
        this.setAnimation(shakeAnimation(5));
    }


    /**
     * 晃動動畫
     *
     * @param counts 1秒鐘晃動多少下
     * @return
     */
    public static Animation shakeAnimation(int counts) {
        Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
        translateAnimation.setInterpolator(new CycleInterpolator(counts));
        translateAnimation.setDuration(5000);
        return translateAnimation;
    }


    public void setPaddingLeft(int paddingleft) {
        setPadding(paddingleft, getPaddingTop(), getPaddingRight(), getPaddingBottom());
    }


}

已將把它發佈到JitPack。
Step 1.Add it in your root build.gradle at the end of repositories:

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Step 2. Add the dependency

dependencies {
        compile 'com.github.s1168805219:ClearEditText:1.0'
}
發佈了303 篇原創文章 · 獲贊 77 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章