带有淡入淡出动画的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;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章