博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 自定义控件实现点击波浪效果(九)
阅读量:6971 次
发布时间:2019-06-27

本文共 5958 字,大约阅读时间需要 19 分钟。

hot3.png

必要条件是这个控件需要实现点击事件

package com.rong.activity;import java.util.ArrayList;import android.R;import android.annotation.SuppressLint;import android.annotation.TargetApi;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Path.Direction;import android.graphics.RectF;import android.os.Build;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.LinearLayout;/** * 一个特殊的LinearLayout,任何放入内部的clickable元素都具有波纹效果,当它被点击的时候, 为了性能,尽量不要在内部放入复杂的元素 * note: long click listener is not supported current for fix compatible bug. */@SuppressWarnings("unused")public class RectangleWaterWave extends LinearLayout implements Runnable {	private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);	private int mTargetWidth;	private int mTargetHeight;	private int mMinBetweenWidthAndHeight;	private int mMaxBetweenWidthAndHeight;	private int mMaxRevealRadius;	private int mRevealRadiusGap;	private int mRevealRadius = 0;	private float mCenterX;	private float mCenterY;	private int[] mLocationInScreen = new int[2];	private boolean mShouldDoAnimation = false;	private boolean mIsPressed = false;	private int INVALIDATE_DURATION = 40;	private View mTouchTarget;	private DispatchUpTouchEventRunnable mDispatchUpTouchEventRunnable = new DispatchUpTouchEventRunnable();	public RectangleWaterWave(Context context) {		super(context);		init();	}	public RectangleWaterWave(Context context, AttributeSet attrs) {		super(context, attrs);		init();	}	@TargetApi(Build.VERSION_CODES.HONEYCOMB)	public RectangleWaterWave(Context context, AttributeSet attrs, int defStyleAttr) {		super(context, attrs, defStyleAttr);		init();	}	private void init() {		setWillNotDraw(false);		mPaint.setColor(Color.RED);	}	@Override	protected void onLayout(boolean changed, int l, int t, int r, int b) {		super.onLayout(changed, l, t, r, b);		this.getLocationOnScreen(mLocationInScreen);	}	private void initParametersForChild(MotionEvent event, View view) {		mCenterX = event.getX();		mCenterY = event.getY();		mTargetWidth = view.getMeasuredWidth();		mTargetHeight = view.getMeasuredHeight();		mMinBetweenWidthAndHeight = Math.min(mTargetWidth, mTargetHeight);		mMaxBetweenWidthAndHeight = Math.max(mTargetWidth, mTargetHeight);		mRevealRadius = 0;		mShouldDoAnimation = true;		mIsPressed = true;		mRevealRadiusGap = mMinBetweenWidthAndHeight / 8;		int[] location = new int[2];		view.getLocationOnScreen(location);		int left = location[0] - mLocationInScreen[0];		int transformedCenterX = (int) mCenterX - left;		mMaxRevealRadius = Math.max(transformedCenterX, mTargetWidth				- transformedCenterX);	}	protected void dispatchDraw(Canvas canvas) {		super.dispatchDraw(canvas);		if (!mShouldDoAnimation || mTargetWidth <= 0 || mTouchTarget == null) {			return;		}		if (mRevealRadius > mMinBetweenWidthAndHeight / 2) {			mRevealRadius += mRevealRadiusGap * 4;		} else {			mRevealRadius += mRevealRadiusGap;		}		this.getLocationOnScreen(mLocationInScreen);		int[] location = new int[2];		mTouchTarget.getLocationOnScreen(location);		int left = location[0] - mLocationInScreen[0];		int top = location[1] - mLocationInScreen[1];		int right = left + mTouchTarget.getMeasuredWidth();		int bottom = top + mTouchTarget.getMeasuredHeight();		canvas.save();		Path path = new Path();//		path.addCircle(180,180, 165, Direction.CCW);		path.addRoundRect(new RectF(left, top, right, bottom), 7, 7,				Direction.CCW);		canvas.clipPath(path);		canvas.drawCircle(mCenterX, mCenterY, mRevealRadius, mPaint);		canvas.restore();		if (mRevealRadius <= mMaxRevealRadius) {			postInvalidateDelayed(INVALIDATE_DURATION, left, top, right, bottom);		} else if (!mIsPressed) {			mShouldDoAnimation = false;			postInvalidateDelayed(INVALIDATE_DURATION, left, top, right, bottom);		}	}	@Override	public boolean dispatchTouchEvent(MotionEvent event) {		int x = (int) event.getRawX();		int y = (int) event.getRawY();		int action = event.getAction();		if (action == MotionEvent.ACTION_DOWN) {			View touchTarget = getTouchTarget(this, x, y);			if (touchTarget != null && touchTarget.isClickable()					&& touchTarget.isEnabled()) {				mTouchTarget = touchTarget;				initParametersForChild(event, touchTarget);				postInvalidateDelayed(INVALIDATE_DURATION);			}		} else if (action == MotionEvent.ACTION_UP) {			mIsPressed = false;			postInvalidateDelayed(INVALIDATE_DURATION);			mDispatchUpTouchEventRunnable.event = event;			postDelayed(mDispatchUpTouchEventRunnable, 40);			return true;		} else if (action == MotionEvent.ACTION_CANCEL) {			mIsPressed = false;			postInvalidateDelayed(INVALIDATE_DURATION);		}		return super.dispatchTouchEvent(event);	}	private View getTouchTarget(View view, int x, int y) {		View target = null;		ArrayList
 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; } @SuppressLint("ClickableViewAccessibility") @Override public boolean performClick() { postDelayed(this, 400); return true; } @Override public void run() { super.performClick(); } private class DispatchUpTouchEventRunnable implements Runnable { public MotionEvent event; @Override public void run() { if (mTouchTarget == null || !mTouchTarget.isEnabled()) { return; } if (isTouchPointInView(mTouchTarget, (int) event.getRawX(), (int) event.getRawY())) { mTouchTarget.performClick(); } } };}

转载于:https://my.oschina.net/547217475/blog/613036

你可能感兴趣的文章
spring mvc 程序
查看>>
20条Linux命令面试问答
查看>>
Jmeter做并发测试(设置集合点)
查看>>
001/Nginx高可用模式下的负载均衡与动静分离(笔记)
查看>>
云服务jdk 升级为 OpenJDK11
查看>>
wp 取消button按下效果
查看>>
【差分约束】
查看>>
C#,java,C++ 等变量命名规则
查看>>
第六次实验
查看>>
python 编码问题
查看>>
进程与线程
查看>>
案例分析
查看>>
A Simple Problem with Integers(线段树入门题)
查看>>
福大软工 · 第七次作业 - 需求分析报告
查看>>
用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 操作符重载和隐式类型转换
查看>>
腾讯云入门
查看>>
20165226 2017-2018-4 《Java程序设计》第6周学习总结
查看>>
linux网络配置命令(二)——ip
查看>>
泛型通配符extends与super的区别
查看>>
openpose模型在AI challenge人体骨骼关键点检测的表现
查看>>