仿Android5.0点击水波效果

本文参考自:点击打开链接 和点击打开链接

package Views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

import java.util.ArrayList;

/**
 * Created by yangxiaoru on 2016/7/7.
 */
public class mLineaerLayout extends LinearLayout {
    private View mTouchTarget;//记录down事件的目标view
    private int mTargetWidth;//目标view的宽度,用于阴影覆盖
    private float mCenterX;//点击的中心x
    private float mCenterY;//点击的中心Y
    private int mRevealRadius = 10;//其实绘制半径
    private Paint mPaint;//画笔
    private MotionEvent event;//延迟分发的up事件

    //这是构造函数
    public mLineaerLayout(Context context) {
        super(context);
        commonInite();
    }

    public mLineaerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        commonInite();

    }

    private void commonInite() {
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.parseColor("#66a0a0a0"));
        mRevealRadius = 10;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int x = (int) event.getRawX();
        int y = (int) event.getRawY();
        int action = event.getAction();
        View touchTarget = getTouchTarget(this, x, y);
        if (action == MotionEvent.ACTION_DOWN) {

            if (touchTarget != null && touchTarget.isClickable() && touchTarget.isEnabled()) {
                mTouchTarget = touchTarget;
                initParametersForChild(event, touchTarget);
            }
        } else if (action == MotionEvent.ACTION_UP) {
            if (touchTarget == mTouchTarget) {
                postInvalidate();//通知重绘
                this.event = event;//记录事件
                return true;//暂时消费事件
            }
        }

        return super.dispatchTouchEvent(event);
    }

    private void initParametersForChild(MotionEvent event, View touchTarget) {
        /**
         * 相对屏幕的坐标-this的起始坐标=相对this的坐标
         */
        mTargetWidth = touchTarget.getMeasuredWidth();
        int[] mLocation = new int[2];
        this.getLocationOnScreen(mLocation);
        mCenterX = event.getRawX() - mLocation[0];
        mCenterY = event.getRawY() - mLocation[1];


    }

    private View getTouchTarget(View view, int x, int y) {
        View target = null;
        ArrayList<View> TouchableViews = view.getTouchables();
        for (View child : TouchableViews) {
            if (isTouchPointInView(child, x, y)) {
                target = child;
                break;
            }
        }

        return target;
    }

    private boolean isTouchPointInView(View view, int x, int y) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        int left = location[0];
        int top = location[1];
        int right = left + view.getMeasuredWidth();
        int bottom = top + view.getMeasuredHeight();
        if (view.isClickable() && y >= top && y <= bottom
                && x >= left && x <= right) {
            return true;
        }
        return false;
    }

    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        if (mTargetWidth <= 0 || mTouchTarget == null) {
            return;
        }
        int[] location = new int[2];
        int[] mLocation = new int[2];
        this.getLocationOnScreen(mLocation);
        mTouchTarget.getLocationOnScreen(location);
        // 计算当前目标view  l t r b
        int top = location[1] - mLocation[1];
        int left = location[0] - mLocation[0];
        int right = left + mTouchTarget.getMeasuredWidth();
        int bottom = top + mTouchTarget.getMeasuredHeight();

        canvas.save();
        canvas.clipRect(left, top, right, bottom);//是以this为参照的坐标系
        canvas.drawCircle(mCenterX, mCenterY, mRevealRadius, mPaint);
        canvas.restore();

        if (mRevealRadius < mTargetWidth && mRevealRadius > 0) {
            if (mRevealRadius >= mTargetWidth / 2) {
                mRevealRadius += 30;
            } else
                mRevealRadius += 20;
            postInvalidateDelayed(50, left, top, right, bottom);
            canvas.restore();
        } else if (mRevealRadius >= mTargetWidth) {
            mRevealRadius = 0;
            postInvalidateDelayed(50, left, top, right, bottom);
            canvas.restore();
            over();

        }
        if (mRevealRadius == 0) {
            mRevealRadius = 10;
        }
    }

    private void over() {

        if (mTouchTarget == null || !mTouchTarget.isEnabled()) {
            return;
        }

        if (isTouchPointInView(mTouchTarget, (int) event.getRawX(), (int) event.getRawY())) {
            //分发延迟的up事件
            mTouchTarget.dispatchTouchEvent(event);
            mRevealRadius = 10;
            mTouchTarget = null;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值