导语

之前发了一个Drawable实现动画效果的帖子,有人找我要过相应圆弧绘制算法,仔细想想那个项目中有些地方还是值得分享出来的,趁现在项目不忙,就准备分享出来。

只有一些算法的东西,代码不涉及具体业务

效果如下(即Activity-A 进入 到Activity-B时会出现的动画效果如上):

实现思路:

主要由两个动画组成,背景动画和按钮动画

背景动画

背景动画可分解为位移上移和圆弧的改变

位移上移可以交给TranslateAnimation 来实现 ,更妙的是可以产生动画插值用来绘制椭圆

弧形改变可以用canvas来绘制,那么动态计算并绘制椭圆即可

动态计算椭圆可以用TranslateAnimation产生的动画插值

按钮动画

根据图片可以看到是新的图片逐渐扩大,从一个点开始逐渐遮盖住了旧的图片,这一点可以用BitmapShader来实现

其他就没了

会用到的技术点

/** * *@param canvas 绘制椭圆 */

private void drawOval(Canvas canvas){

// 起始 角度

float startAngle = 0f;

// 划过角度

float sweepAngle = 180;

final RectF rect = new RectF(0,0,400,100);

Path path = new Path();

path.addArc(rect,startAngle,sweepAngle);

}

Shader是着色器,BitmapShader是bitmap着色器,可以将一个Bitmap对象绘制到画布上.

阻尼振动曲线如下图

其实分析曲线后就能发现 其实就是指数函数(无限趋近于0)和 余弦曲线的结合而已。

实现过程

因为主要是背景动画和按钮动画,所以也拆成两部分

背景动画的实现

动画过程分析

位移动画可以不表,因为很简单,以一种速率 最多加一个速度叠加器即可

椭圆可以看到先是移出时椭圆向下最大,然后慢慢缩小,最后在位移到 整体 1/2处椭圆为0,然后又向屏幕上方鼓出,慢慢增大,到 位移到最大位置时椭圆最大

到最大位移位置后,圆弧以阻尼振动慢慢缩小,及至椭圆为0

动画过程实现

1. 创建位移动画

同时创建出 0f - 1.0f 的时间插值

/** * *@return 得到上移动画 */

private AnimationSet getAnimationSet(){

// 之所以用 AnimationSet,是为了可能加入进来的其他动画效果

final AnimationSet animationSet = new AnimationSet(true);

animationSet.setDuration(1600);

// TranslateAnimation.RELATIVE_TO_SELF 相对位置

TranslateAnimation translateAnimation = new TranslateAnimation(

TranslateAnimation.RELATIVE_TO_SELF,0,

TranslateAnimation.RELATIVE_TO_SELF,0,

TranslateAnimation.RELATIVE_TO_SELF,1.0f,

TranslateAnimation.RELATIVE_TO_SELF,0){

/** * 回调间隔在10 ms 左右 *@param interpolatedTime 即为时间插值 0f - 1f, *@param t */

@Override

protected void applyTransformation(float interpolatedTime, Transformation t) {

super.applyTransformation(interpolatedTime, t);

// 半屏动画 设置插值

mHalfScreenDrawable.setPercent(interpolatedTime);

// 按钮动画 设置插值

mRippleButtonDrawable.setPercent(interpolatedTime);

}

};

animationSet.addAnimation(translateAnimation);

return animationSet;

}

2. 创建绘制弧线

向下的弧线可以理解为一块正方形和椭圆重叠,当绘制上/下半椭圆以及正确的混合模式即可得到一个正确的圆弧

// 图片混合模式为

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));

即 当时间插值 为 0f - 0.5f的时候,控制椭圆所在矩形高度由大减小到0,同时绘制椭圆下半部

当时间插值为 0.5f - 1.0f的时候,控制椭圆所在矩形高度由0增大到最大,同时绘制椭圆上半部

当到1.0f时,根据阻尼振动函数 计算出递增插值下 包含椭圆 矩形的高度绘制半部椭圆即可

/** * 设置时间插值,并根据插值计算椭圆所在矩形高度,从而得到不同的椭圆弧度 *@param value */

public void setPercent(float value) {

// 向下圆弧,绘制下半部椭圆

if (value <= 0.5f) {

mStartAngle = 0;

final float top = mBottomRectF.top - mHeightTopRect * (0.5f - value);

final float bottom = mBottomRectF.top + mHeightTopRect * (0.5f - value);

mTopRectF.set(mTopRectF.left, top, mTopRectF.right, bottom);

} else {

// 向上圆弧,绘制上半部椭圆

mStartAngle = 180;

final float top = mBottomRectF.top - mHeightTopRect * (value * 2f - 1f) / 2f;

final float bottom = mBottomRectF.top + mHeightTopRect * (value * 2f - 1f) / 2f;

mTopRectF.set(mTopRectF.left, top, mTopRectF.right, bottom);

if (value == 1.0f) {

// 当到1.0f时,开始绘制阻尼振动

startBackAnimation();

}

}

invalidateSelf();

}

/** * // 当到1.0f时,开始绘制阻尼振动画 */

private void startBackAnimation() {

isInBounceMode = true;

handler.sendEmptyMessageDelayed(100, 5);

}

/** * TODO: 15/12/8 要修改为弱引用 */

private Handler handler = new Handler() {

@Override

public void dispatchMessage(Message msg) {

super.dispatchMessage(msg);

invalidateSelf();

// 根据当前 阻尼函数计算得出的Y坐标计算得到包含椭圆矩形的上下Y坐标

final float top = mBottomRectF.top - Math.abs(mBounceY) / 2;

final float bottom = mBottomRectF.top + Math.abs(mBounceY) / 2;

mTopRectF.set(mTopRectF.left, top, mTopRectF.right, bottom);

// 根据当前 阻尼函数计算得出的Y坐标计算得到startAngel

if (mBounceY > 0) {

mStartAngle = 180;

} else {

mStartAngle = 0;

}

}

};

/** * 根据cursor插值,计算 阻尼 Y实时坐标 *@param x *@return 阻尼振动函数 */

private double getBounceY(long x) {

if (x == 0)

return 0;

// 指数函数

double bounceRate = Math.exp(-0.06 * x);

if (bounceRate < 0.0001) {

isInBounceMode = false;

}

// 增益函数和余弦曲线合并,就是阻尼函数曲线

return bounceRate * Math.cos(0.3 * x);

}

到这里,绘制背景动画关键代码已经完毕

按钮动画的实现

动画过程分析

可以看到是一张旧图片上,新的图片逐渐扩大,发现其实是两个动画的集合 ,一个是新的图片不停变大(保持圆形),第二个是新的图片圆心坐标有变化

更深一步分析是新图片在 时间插值 0f-1f,半径从0-最大,圆心从 图片3/4处,变为最后1/2处

动画过程实现

时间插值可以用之前创建出来的

如果你已经看过了并指导 BitmapShader是干什么的那么应该已经有了思路了吧?

/** * 构造参数 * *@param bitmap 新的图片 *@param oldBitmap 旧图片 */

public RippleButtonDrawable(Bitmap bitmap, Bitmap oldBitmap) {

mBitmapNew = bitmap;

mBitmapOld = oldBitmap;

// 设置图片着色器

BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,

Shader.TileMode.CLAMP);

mPaintNew = new Paint();

mPaintNew.setAntiAlias(true);

mPaintNew.setShader(bitmapShader);

mWidth = mBitmapNew.getWidth();

mHeight = mBitmapNew.getHeight();

mPaintOld = new Paint();

}

@Override

public void draw(Canvas canvas) {

// 绘制旧图片

canvas.drawBitmap(mBitmapOld, 0, 0, mPaintOld);

// 绘制圆形新图片

canvas.drawCircle(

getXCoordinateOfCenter(mPercent),

getYCoordinateOfCenter(mPercent),

getRadiusWithPercent(mPercent),

mPaintNew);

}

就这样就好了,是不是很简单???

有更多的问题可以联系我

android 实现果冻动画效果,Android果冻效果(阻尼动画)相关推荐

  1. Android果冻效果(阻尼动画)

    导语 之前发了一个Drawable实现动画效果的帖子,有人找我要过相应圆弧绘制算法,仔细想想那个项目中有些地方还是值得分享出来的,趁现在项目不忙,就准备分享出来. 只有一些算法的东西,代码不涉及具体业 ...

  2. Android ProgressBar 加载中界面实现(loading 动画) 实现菊花的效果

    实现的效果图如下: 使用方法ProgressBar ,如果感觉 这个动画不是自己想要的,需要根据ui的图片来实现只需要将xml中的animated-rotate 修改为animation-list 贴 ...

  3. android联动动画,利用 CollapsingToolbarLayout 完成联动的动画效果

    最近项目中需要实现个动画效果,研究了下这里做下简单的分享. 效果图如下: 示例.gif 最初的想法是自己去利用 Android 的嵌套滚动机制,去实现上面的嵌套滚动效果.但最后为了开发效率直接利用了 ...

  4. android ui动画效果怎么做,AndroidUI 布局动画-为列表添加布局动画效果

    新建一个Android project ,使MainActivity 继承自 ListActivity: public class MainActivity extends ListActivity ...

  5. android图片gif动画效果,android中类似于gif 实现图片的动画效果

    案例:实现gif动画效果,连续播放图片 由于是转载的,也就没必要多说,直接上代码 案例:在android中实现gif动态图片的效果: EarthAnimationActivity.java packa ...

  6. Android项目实战(四):ViewPager切换动画(3.0版本以上有效果)

    原文:Android项目实战(四):ViewPager切换动画(3.0版本以上有效果) 学习内容来自"慕课网" 一般APP进去之后都会有几张图片来导航,这里就学习怎么在这张图片切换 ...

  7. android 页面翻转进场动画_Android实现翻转及延迟动画效果

    最近在学习安卓一些动画效果制作.做了点翻转和延迟入场动画的效果,并做了些封装.动画基于属性动画实现的,所以仅能在api11以后运行,不过现在应该也没有11以前的机器了吧...废话不多说,先上效果再贴代 ...

  8. android 加载动画效果_这效果炸了,网易云音乐“宇宙尘埃”特效

    本文作者 作者:Mlx 链接: https://juejin.im/post/6871049441546567688 本文由作者授权发布. 1前言 前段时间,女朋友用网易云音乐的时候看到一个宇宙尘埃特 ...

  9. android属性动画作用范围,Android开发之动画效果浅析(一)

    程序运行效果图: Android动画主要包含补间动画(Tween)View Animation.帧动画(Frame)Drawable Animation.以及属性动画Property Animatio ...

  10. Android\OPhone动画分析之翻转效果

    看到很多人在问如何实现三维的翻转效果,所以今天在这里简单的给大家分析一下,其实在APIDemo中就有这样一个例子,那么我们就以其为例来学习Android中的翻转动画效果的实现,首先看一下运行效果如下图 ...

最新文章

  1. exchange 2010-诊断小工具简解
  2. NOI模拟题4 Problem C: 填格子(board)
  3. Ubuntu16.04/18.04 安装配置JDK 1.8 环境( Linux )
  4. 关于FactoryBean 和BeanFactory
  5. .NET开发者的机遇与Web Blazor基础(有彩蛋)
  6. 关于“数据分析”如何快速入门一些基本思路
  7. MySQL安装叫重启_MySQL重启命令和MySQL数据库安装目录的操作过程
  8. log函数 oracle power_Oracle 函数大全详细介绍
  9. weblogic数据源配置oracle and mysql
  10. matlab偏最小二乘法及其检验
  11. PHP_XLSXWriter 样式,使用PHP_XLSXWriter代替PHPExcel
  12. 163等各种邮箱端口号设置
  13. 《云计算技术与应用基础》课程标准
  14. Java(但行好事 莫问前程) 1
  15. surface pro 6 黑苹果_surface pro 6 黑苹果
  16. 公司价值评估-自由现金流法
  17. matlab如何去除图像白边_MATLAB去除白边
  18. iPhone越狱检测
  19. 是不是安装了anaconda就不用安装python呢_dnf魔界是怎么样的,今天来带大家见识一下...
  20. zoj 2965 Accurately Say CocaCola!

热门文章

  1. stata判断变量是不是唯一标识的命令?
  2. linux/android系统开发,高级adb 命令汇总
  3. 详细不啰嗦,电脑重装系统win10教程分享
  4. Android10 lowmemorykiller
  5. 不良资产证券化信披 担任怎样的角色
  6. 怎么样把谷歌浏览器的默认背景颜色设置成绿豆沙
  7. 计算机一级考试B十类理论题,10计算机一级统考理论题.doc
  8. POJ-1436Horizontally Visible Segments
  9. POJ 1436 Horizontally Visible Segments(线段树区间修改)
  10. JS中的一些条件判断语句