自己实现Android动画算法 之 平移动画算法 !!!!
2012-04-05 15:18
309 查看
Android在3.0版本之前只提供了基本的位移、旋转、缩放等动画,这些动画可以通过xml来配置,也可以用java代码来写,当然,从3.0开始就提供了不同的类和接口(ValueAnimator、ObjectAnimator、AnimatorSet)来编写自己的动画,笔者曾经尝试将这些新的类搬运至2.X系统,发现报错.......(Native
Method),很明显,这是由于内部的一些东西的变更导致无法搬移,这里浅析一下Android的位移动画以及其插值的算法。
位移动画有多种时间插值算法,比如我们常用的有AccelerateDecelerateInterpolator、AccelerateInterpolator、DecelerateInterpolator等,这些插值算法是为了给平移动画添加各种效果,加速减速、加速、减速等,这里举个例子。
AccelerateDecelerateInterpolatorinterpolator
= new AccelerateDecelerateInterpolator();
TranslateAnimation translateAnim2
= new TranslateAnimation(0,-300,0,-500);
translateAnim2.setDuration(600);
translateAnim2.setInterpolator(interpolator);
translateAnim2.setFillAfter(true);
mImageView.startAnimation(translateAnim2);
这里是让ImageView进行平移动画,同时,平移的效果是先加速,再减速。
那么,插值是如何让平移动画先加速再减速的呢?
首先,系统会将所有的动画时间平均划分到(0,1)这个范围内,0就是动画开始的时间,1就是动画结束的时间,那么,既然将时间划分成这个范围,也就意味着将动画移动长度划进行了这样一个划分,比如现在插值input为 0.2,我用公式计算得到一个值interpolatedTime
为0.3,那么我就让这个View的x坐标值运动到mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime),mFromXDelta 为运动起始x坐标,mToXDelta为运动终点x坐标,那这样的话,就运动了总长度的0.3,一直到interpolatedTime
的值为1,整个动画就结束了。
看一下DecelerateInterpolator的算法,(1.0f - (1.0f - input) * (1.0f - input)),这是一个自变量范围在[0,1]、函数值范围也在[0,1]的连续函数,本人了解自变量就是总时间的比例(取值为%0,100%),函数值就是运动长度的比例(取值为%0,100%)。其函数图:
很明显了,函数的斜率其实就是速度,如图,函数的斜率是不断减小的,于是产生了减速的效果。那么,写一个自己的时间插值只需用满足:
1.函数是连续的,如果不连续,动画效果将不会连续
2.自变量范围[0,1],自变量的值是系统生成的
3.函数值域为[0,1]
于是,我自己写了一个加速减速效果(系统自己提供的加速减速效果实在是太不明显了),代码如下:
if (t < 0.4) {
return (float)(t*t);
}else if (t >= 0.4 &&t <= 0.6) {
return (float)(3.4*t - 1.2);
}else
return (float)(1.0f - (1.0f - t) * (1.0f - t));
函数图象如下:
这样加速减速效果就非常明显啦!当然啦,自己去创建一个类似DecelerateInterpolator的类,将这个算法写入getInterpolation()方法就可以啦
同时,我想,旋转等效果的动画算法原理也应该是一样的,所以,咱们可以自己去实现很多效果的动画!
如果有了解错误的地方,还请大侠们指出!
Method),很明显,这是由于内部的一些东西的变更导致无法搬移,这里浅析一下Android的位移动画以及其插值的算法。
位移动画有多种时间插值算法,比如我们常用的有AccelerateDecelerateInterpolator、AccelerateInterpolator、DecelerateInterpolator等,这些插值算法是为了给平移动画添加各种效果,加速减速、加速、减速等,这里举个例子。
AccelerateDecelerateInterpolatorinterpolator
= new AccelerateDecelerateInterpolator();
TranslateAnimation translateAnim2
= new TranslateAnimation(0,-300,0,-500);
translateAnim2.setDuration(600);
translateAnim2.setInterpolator(interpolator);
translateAnim2.setFillAfter(true);
mImageView.startAnimation(translateAnim2);
这里是让ImageView进行平移动画,同时,平移的效果是先加速,再减速。
那么,插值是如何让平移动画先加速再减速的呢?
首先,系统会将所有的动画时间平均划分到(0,1)这个范围内,0就是动画开始的时间,1就是动画结束的时间,那么,既然将时间划分成这个范围,也就意味着将动画移动长度划进行了这样一个划分,比如现在插值input为 0.2,我用公式计算得到一个值interpolatedTime
为0.3,那么我就让这个View的x坐标值运动到mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime),mFromXDelta 为运动起始x坐标,mToXDelta为运动终点x坐标,那这样的话,就运动了总长度的0.3,一直到interpolatedTime
的值为1,整个动画就结束了。
看一下DecelerateInterpolator的算法,(1.0f - (1.0f - input) * (1.0f - input)),这是一个自变量范围在[0,1]、函数值范围也在[0,1]的连续函数,本人了解自变量就是总时间的比例(取值为%0,100%),函数值就是运动长度的比例(取值为%0,100%)。其函数图:
很明显了,函数的斜率其实就是速度,如图,函数的斜率是不断减小的,于是产生了减速的效果。那么,写一个自己的时间插值只需用满足:
1.函数是连续的,如果不连续,动画效果将不会连续
2.自变量范围[0,1],自变量的值是系统生成的
3.函数值域为[0,1]
于是,我自己写了一个加速减速效果(系统自己提供的加速减速效果实在是太不明显了),代码如下:
if (t < 0.4) {
return (float)(t*t);
}else if (t >= 0.4 &&t <= 0.6) {
return (float)(3.4*t - 1.2);
}else
return (float)(1.0f - (1.0f - t) * (1.0f - t));
函数图象如下:
这样加速减速效果就非常明显啦!当然啦,自己去创建一个类似DecelerateInterpolator的类,将这个算法写入getInterpolation()方法就可以啦
同时,我想,旋转等效果的动画算法原理也应该是一样的,所以,咱们可以自己去实现很多效果的动画!
如果有了解错误的地方,还请大侠们指出!
相关文章推荐
- 自己实现Android动画算法 之 平移动画算法
- Android实现循环平移动画示例
- Android Acitivy切换平移动画效果实现
- Android Acitivy切换平移动画效果实现
- Android中侧滑菜单效果实现(主界面和菜单界面实现平移、缩放、滚动动画)
- Android 实现属性动画平移,旋转,缩放,渐变 《H》
- Android自己定义View画图实现拖影动画
- Android使用原生动画工具类实现平移动画
- Android 平移动画+缩放动画=集合动画->实现开机启动页+通过线程休眠事件跳转到主界面
- Android 补间动画,具体介绍了透明度、平移,旋转,缩放4种动画效果的实现,简单易懂
- Android 通过Animate硬编码实现简单的平移、旋转、缩放及透明度动画过程
- Android动画 实现开关按钮动画(属性动画之平移动画)实例代码
- Android高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现
- Android高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现
- Android 屏幕动画原理 我说的 是坐标 这样 怎么实现 自己写算法 任何问题都没有了!
- Android中用Matrix实现ImageView里的图片平移和缩放动画
- Android 属性动画 实现view翻转 旋转 平移 拉伸 透明度 背景颜色变换
- android动画介绍之 自己定义Animation动画实现qq抖一抖效果
- Android 手机卫士--平移动画实现
- Android 手机卫士实现平移动画示例