关闭

android水波纹RippleEffect源码解析

标签: android水波纹
1571人阅读 评论(0) 收藏 举报
分类:

1.废话

来到公司的第一个任务,写出水波纹,仔细想想具体思路,点击一下就有水波 ,那也不能那里点击都有水波吧,那就继承一个相对布局呗,然后响应点击事件,绘画一个波纹,那就是动画了,OK,先去google,发现一个开源库 RippleView 最低兼容到2.3正好也是老大要求的兼容嘛。


效果图


github地址:https://github.com/traex/RippleEffect 作者没有做过多介绍事实是也没多少代码 github是AS构建的

2.作者思路呢:

① 继承相对布局,复写三个构造方法,实现init方法-获取属性,设置属性 
属性分别是:

  • app:rv_alpha [integer def:90 0-255] --> Alpha of the ripple
  • app:rv_framerate [integer def:10] --> Frame rate of the ripple animation
  • app:rv_rippleDuration [integer def:400] --> Duration of the ripple animation
  • app:rv_ripplePadding [dimension def:0] --> Add a padding to the ripple
  • app:rv_color [color def:@android:color/white] --> Color of the ripple
  • app:rv_centered [boolean def:false] --> Center ripple in the child view
  • app:rv_type [enum (simpleRipple, doubleRipple) def:simpleRipple] --> Simple or double ripple
  • app:rv_zoom [boolean def:false] --> Enable zoom animation
  • app:rv_zoomDuration [integer def:150] --> Duration of zoom animation
  • app:rv_zoomScale [float def:1.03] --> Scale of zoom animation
源码还给了长按点击事件 
② 自定义布局嘛,肯定还有OnDraw 绘画
 判断动画是否开始,未开始先设置一些参数,而且判断是否到达下一次刷新的时间,到了就刷新一些,执行一次绘画,同时绘画的时候还要判断一些类型,比如type 你在xml里面设置的
		super.draw(canvas);
//		判断动画是否开始
		if (animationRunning) {
//是否已经到达持续时间
			if (rippleDuration <= timer * frameRate) {
				animationRunning = false;
				timer = 0;
				durationEmpty = -1;
				timerEmpty = 0;
				canvas.restore();
				invalidate();
				if (onCompletionListener != null)
					onCompletionListener.onComplete(this);
				return;
			} else
				canvasHandler.postDelayed(runnable, frameRate);

			if (timer == 0)
				canvas.save();
//   画圆
			canvas.drawCircle(x, y, (radiusMax * (((float) timer * frameRate) / rippleDuration)), paint);
//设置颜色
			paint.setColor(Color.parseColor("#ffff4444"));
//判断是否是type1 
			if (rippleType == 1 && originBitmap != null && (((float) timer * frameRate) / rippleDuration) > 0.4f) {
				if (durationEmpty == -1)
					durationEmpty = rippleDuration - timer * frameRate;

				timerEmpty++;
				final Bitmap tmpBitmap = getCircleBitmap(
						(int) ((radiusMax) * (((float) timerEmpty * frameRate) / (durationEmpty))));
				canvas.drawBitmap(tmpBitmap, 0, 0, paint);
				tmpBitmap.recycle();
			}

			paint.setColor(rippleColor);

			if (rippleType == 1) {
				if ((((float) timer * frameRate) / rippleDuration) > 0.6f)
					paint.setAlpha((int) (rippleAlpha
							- ((rippleAlpha) * (((float) timerEmpty * frameRate) / (durationEmpty)))));
				else
					paint.setAlpha(rippleAlpha);
			} else
				paint.setAlpha((int) (rippleAlpha - ((rippleAlpha) * (((float) timer * frameRate) / rippleDuration))));

			timer++;
		}
	

3.大家都看到上面了,如果动画没开始是不会进行绘制的,所以要在touch时间中进行监控


@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (gestureDetector.onTouchEvent(event)) {
			animateRipple(event);
			sendClickEvent(false);
		}
		return super.onTouchEvent(event);
	}

animateRipple 开始波浪动画

	private void createAnimation(final float x, final float y) {
		// 有不有开始
		if (this.isEnabled() && !animationRunning) {
			//要不要进行缩放效果同时也是在xml里面设置的
			if (hasToZoom)
				this.startAnimation(scaleAnimation);

			radiusMax = Math.max(WIDTH, HEIGHT);

			if (rippleType != 2)
				radiusMax /= 2;

			radiusMax -= ripplePadding;

			if (isCentered || rippleType == 1) {
				this.x = getMeasuredWidth() / 2;
				this.y = getMeasuredHeight() / 2;
			} else {
				this.x = x;
				this.y = y;
			}

			animationRunning = true;

			if (rippleType == 1 && originBitmap == null)
				originBitmap = getDrawingCache(true);

			invalidate();
		}
	}

4.其实还用了缓存的数据进行再次试用

	private Bitmap getCircleBitmap(final int radius) {
		final Bitmap output = Bitmap.createBitmap(originBitmap.getWidth(), originBitmap.getHeight(),
				Bitmap.Config.ARGB_8888);
		final Canvas canvas = new Canvas(output);
		final Paint paint = new Paint();
		final Rect rect = new Rect((int) (x - radius), (int) (y - radius), (int) (x + radius), (int) (y + radius));

		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		canvas.drawCircle(x, y, radius, paint);

		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
		canvas.drawBitmap(originBitmap, rect, rect, paint);

		return output;
	}



5.源码下载


点击下载

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

安卓学习笔记---Android源码解析--Material Design之水波纹点击效果RippleEffect使用

今天老板跟我说,能不能加一个点击效果,要不然用户不知道他是否已经点击了,我说好的,刚开始我是使用的selector添加效果的,UI看了之后说好丑啊,能不能改的好看点啊,哎,,,果然好难啊,咋滴都得好看...
  • juhua2012
  • juhua2012
  • 2016-09-12 14:53
  • 1534

图像处理之水波纹扩散效果(water ripple effect)

实现一个常见PS特效,water ripple effect, 水波纹扩散效果,主要是利用sine函数模拟 水波纹扩散效果,使用双线性插值完成像素提供。
  • jia20003
  • jia20003
  • 2013-10-26 22:38
  • 12470

RippleEffect(水波纹效果)的实现

学习 谷歌 material design的交互设计、向新技术靠拢~  由于谷歌的只有在5.0+才可以有这个效果~ 而我们手头手机大部分还是4.+的、因此自己去实现这个效果、让各种版本的都可以用 ...
  • u011733020
  • u011733020
  • 2015-12-02 11:20
  • 1850

Android源码解析--Material Design之水波纹点击效果RippleEffect使用

Android Materail Design之RippleEffect水波涟漪的使用源码解析,点击控件实现水波涟漪效果,加到你的app中会显得很高大上,分析一下源码,看看具体怎么实现的。 ndroi...
  • lyhhj
  • lyhhj
  • 2015-09-16 23:21
  • 5257

安卓学习笔记---Android源码解析--Material Design之水波纹点击效果RippleEffect使用

今天老板跟我说,能不能加一个点击效果,要不然用户不知道他是否已经点击了,我说好的,刚开始我是使用的selector添加效果的,UI看了之后说好丑啊,能不能改的好看点啊,哎,,,果然好难啊,咋滴都得好看...
  • juhua2012
  • juhua2012
  • 2016-09-12 14:53
  • 1534

Android 自定义控件之RippleEffect水波纹效果

  • 2016-03-30 17:01
  • 2.61MB
  • 下载

Android自定义View 实现水波纹动画引导源码

  • 2017-01-17 10:01
  • 26.11MB
  • 下载

Android——实现渐变色水波纹效果源码

项目中使用到的效果,效果图如下: 代码实现: public class WaveView extends View { private Paint mPaint, mCricleP...
  • qq_22770457
  • qq_22770457
  • 2017-02-22 20:34
  • 1025

Android自定义控件:Android L控件点击水波纹的实现(源码 + Demo)

  • 2015-01-18 14:52
  • 1.45MB
  • 下载

水波纹效果和工程源码【效果非常逼真】

  • 2010-12-14 14:58
  • 398KB
  • 下载
    个人资料
    • 访问:448638次
    • 积分:6694
    • 等级:
    • 排名:第4112名
    • 原创:237篇
    • 转载:4篇
    • 译文:0篇
    • 评论:154条
    个人介绍

    Android+前端+后台=小新菜鸟


    如有问题咨询请发邮件至619338136@qq.com

    博客专栏
    最新评论