Android 自定义Button波纹效果

随着Material Design越来越流行,当然少不了Button的波纹效果这种需求,一开始我觉得这玩意儿应该挺麻烦的,但是找了些别人写的库来看了一下,发现也就那么回事,所以自己也自定义了一个RippleButton
主要就是监听 view的touch事件
直接上代码

public class RippleButton extends AppCompatButton {
    private int mX;
    private ObjectAnimator mAnimator;
    private int mCurRadius = 0;
    private RadialGradient mRadialGradient;
    private Paint mPaint;
    private float mDensity;
    private Rect mRect;
    private float mDownY;

    public RippleButton(Context context) {
        super(context);
        init();
    }

    public RippleButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RippleButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        setLayerType(LAYER_TYPE_SOFTWARE,null);
        mDensity = getContext().getResources().getDisplayMetrics().density;
        mPaint = new Paint();
    }

    private int dp(int dp) {
        return (int) (dp * mDensity + 0.5f);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (mX != event.getX()) {
            mX = (int) event.getX();
            mRect = new Rect(getLeft(), getTop(), getRight(), getBottom());
        }

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (mDownY==0){
                mDownY = event.getY();
            }
            setRadius(dp(60));
            return true;
        }else if (event.getAction() ==MotionEvent.ACTION_MOVE){
            if (mAnimator != null && mAnimator.isRunning()) {
                mAnimator.cancel();
            }
            if (!mRect.contains(
                    getLeft() + (int) event.getX(),
                    getTop() + (int) event.getY())) {
                setRadius(0);
            } else {

                setRadius(dp(60));
            }
            return true;
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            if (mRect.contains(
                    getLeft() + (int) event.getX(),
                    getTop() + (int) event.getY())){
                if (mAnimator != null && mAnimator.isRunning()) {
                    mAnimator.cancel();
                }

                if (mAnimator == null) {
                    mAnimator = ObjectAnimator.ofInt(this,"radius",dp(50), getWidth());
                }
                mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
                mAnimator.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        setRadius(0);
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {

                    }

                    @Override
                    public void onAnimationRepeat(Animator animation) {

                    }
                });
                mAnimator.start();
            }

        }

        return super.onTouchEvent(event);
    }

    public void setRadius(final int radius) {
        mCurRadius = radius;
        if (mCurRadius > 0) {
            mRadialGradient = new RadialGradient(mX, mDownY, mCurRadius, Color.parseColor("#22000000"), Color.parseColor("#22000000"), Shader.TileMode.MIRROR);
            mPaint.setShader(mRadialGradient);
        }
        postInvalidate();
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(mX, mDownY, mCurRadius, mPaint);
    }
}

这里是可以设置渐变效果的,好像自带的也没有,所以我也没有设置渐变效果
简单点理解就是根据不同的touch事件画圆就行了
效果如下
这里写图片描述

猜你喜欢

转载自blog.csdn.net/villa_mou/article/details/78707891