帶有淡入淡出動畫的ClearEditText

這個是在原有代碼的基礎上修改的,原有的ClearEditText 類,其實就是一個EditText, 在edittext的內容不爲空的情況下,顯示右邊一個“X”就是清空按鈕,而這個X基本就是一個drawable,但是這個drawable的出現消失,沒有任何動畫效果,就是突然蹦出來,個人感覺太生硬! 所以有了如下代碼:

public class ClearEditText extends AppCompatEditText implements TextWatcher {


    private Drawable mClearDrawable = null;

    /**
     * 是否開啓動畫
     */
    private boolean isAnimationEnable = true;

    /**
     * 是否淡出、淡入動畫正在執行
     */
    private boolean isInFadeOut = false;
    private boolean isInFadeIn = false;

    /**
     * 設置動畫時長
     */
    private int mDuration = 120;

    private int mPreviousLength = 0;

    private ValueAnimator fadeOut, fadeIn;


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


    private void init() {
        addTextChangedListener(this);
    }

    @Override
    public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) {
        super.setCompoundDrawables(left, top, null, bottom);
    }

    public void setDrawable(Drawable drawable) {

        if (drawable != null) {

            if (mClearDrawable != null
                    && drawable == mClearDrawable)
                return;

            mClearDrawable = drawable;
            mClearDrawable.setBounds(
                    0,
                    0,
                    mClearDrawable.getIntrinsicWidth(),
                    mClearDrawable.getIntrinsicHeight());
            doChange();
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (event.getAction() == MotionEvent.ACTION_UP) {

            //動畫執行過程中不響應點擊事件
            if (!isInFadeIn && !isInFadeOut && mClearDrawable != null) {

                boolean touchable = event.getX() > (getWidth() - getPaddingRight() - mClearDrawable.getIntrinsicWidth())
                        && (event.getX() < ((getWidth() - getPaddingRight())));

                if (touchable) {
                    setText("");
                }
            }


        }
        return super.onTouchEvent(event);
    }

    public void setDuration(int duration) {
        mDuration = duration;
    }

    public boolean isAnimationEnable() {
        return isAnimationEnable;
    }

    public void setAnimationEnable(boolean animationEnable) {
        isAnimationEnable = animationEnable;
    }


    private void setClearIconVisible(boolean visible) {

        final Drawable[] CompoundDrawables = getCompoundDrawables();

        //在字符串變化非常快的時候動畫來不及執行
        //先取消之前的動畫
        if (fadeIn != null && isInFadeIn) {
            fadeIn.cancel();
            isInFadeIn = false;
        }

        if (fadeOut != null && isInFadeOut) {
            fadeOut.cancel();
            isInFadeOut = false;
        }

        if (visible && mClearDrawable != null) {

            if (isAnimationEnable) {
                mClearDrawable.setAlpha(0);
                super.setCompoundDrawables(CompoundDrawables[0],
                        CompoundDrawables[1], mClearDrawable, CompoundDrawables[3]);
                isInFadeIn = true;
                fadeIn = ValueAnimator.ofInt(0, 255);
                fadeIn.setDuration(mDuration);
                fadeIn.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {

                        int alpha = (int) animation.getAnimatedValue();

                        mClearDrawable.setAlpha(alpha);

                        if (alpha == 255) {
                            isInFadeIn = false;
                        }

                    }
                });

                fadeIn.start();

            } else {
                isInFadeIn = false;
                super.setCompoundDrawables(CompoundDrawables[0],
                        CompoundDrawables[1], mClearDrawable, CompoundDrawables[3]);

            }

        } else if (!visible && mClearDrawable != null) {

            if (isAnimationEnable) {

                isInFadeOut = true;
                fadeOut = ValueAnimator.ofInt(255, 0);
                fadeOut.setDuration(mDuration);
                fadeOut.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {

                        int alpha = (int) animation.getAnimatedValue();

                        mClearDrawable.setAlpha(alpha);

                        if (alpha == 0) {
                            isInFadeOut = false;

                            ClearEditText.super.setCompoundDrawables(CompoundDrawables[0],
                                    CompoundDrawables[1], null, CompoundDrawables[3]);
                        }

                    }
                });

                fadeOut.start();
            } else {
                isInFadeOut = false;
                super.setCompoundDrawables(CompoundDrawables[0],
                        CompoundDrawables[1], null, CompoundDrawables[3]);
            }
        }

    }



    private void doChange() {

        setClearIconVisible(getText().toString().length() > 0);
    }

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

        //只有字符串是從有到無,或從無到有才會執行
        //比如:字符串長度從1變成2 dochange方法不會執行
        if ((mPreviousLength == 0 && s.length() > 0)
                || (mPreviousLength > 0 && s.length() == 0)) {
            doChange();
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
                                  int after) {
        mPreviousLength = s.length();
    }

    @Override
    public void afterTextChanged(Editable s) {

    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        release();
    }

    private void release() {

        if (mClearDrawable != null) {
            mClearDrawable = null;
        }

        //必須釋放,否則可能退出時動畫還在執行,但mClearDrawable
        //在上面釋放了,所以不釋放可能會有空指針異常
        if (fadeIn != null) {
            fadeIn.cancel();
            fadeIn.removeAllUpdateListeners();
            fadeIn = null;
        }

        if (fadeOut != null) {
            fadeOut.cancel();
            fadeOut.removeAllUpdateListeners();
            fadeOut = null;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章