android动画之interpolator和typeEvaluator用法详解
Interpolator (插值器)
我们在写动画的时候为了达到某种效果往往需要设置插值器,用来真实的模拟生活中的场景。
Interpolator (插值器)被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等。
结构图:
常见的插值器:
AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
AnticipateInterpolator 开始的时候向后然后向前甩
AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
BounceInterpolator 动画结束的时候弹起
CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
DecelerateInterpolator 在动画开始的地方快然后慢
LinearInterpolator 以常量速率改变
OvershootInterpolator 向前甩一定值后再回到原来位置
如果上面的插值器不满足你的要求,你可以自定义插值器。
我们看一个效果
这里我自定义了一个插值器,实现匀速的转动
public class MyInterpolator extends LinearInterpolator {
private float factor;
public MyInterpolator() {
this.factor = 0.15f;
}
@Override
public float getInterpolation(float input) {
return (float) (Math.pow(2, -10 * input)
* Math.sin((input - factor / 4) * (2 * Math.PI) / factor) + 1);
}
}
接下来我们要说说Android属性动画的估值器。
TypeEvaluator(估值器)
TypeEvaluator(估值器):ValueAnimator.ofObject()函数来做动画效果的时候就会用到,作用是估算我们动画执行到什么程度,什么时间执行什么动画的一个类。估值器用到了TypeEvaluator这个接口:
public interface TypeEvaluator<t> {
/**
* @param fraction The fraction from the starting to the ending values
* @param startValue The start value.
* @param endValue The end value.
* @return A linear interpolation between the start and end values, given the
* <code>fraction</code> parameter.
*/
public T evaluate(float fraction, T startValue, T endValue);
}
这里有三个函数:fraction: 表示当前这段数值变化值得比例,startValue:表示当前这段数值变化的开始值,endValue: 表示当前这段数据变化的结束值。
估值器在哪里用得到呢,很多地方,举一个简单的例子,如用属性动画执行帧动画效果。
那么估值器是怎么工作的呢,我们来看下ValueAnimator的源码,其中在KeyframeSet类里有这么一个方法,这就是估值器工作的地方
public Object getValue(float fraction) {
// Special-case optimization for the common case of only two keyframes
if (mNumKeyframes == 2) {
if (mInterpolator != null) {
fraction = mInterpolator.getInterpolation(fraction);
}
return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(),
mLastKeyframe.getValue());
}
if (fraction <= 0f) {
final Keyframe nextKeyframe = mKeyframes.get(1);
final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
final float prevFraction = mFirstKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) /
(nextKeyframe.getFraction() - prevFraction);
return mEvaluator.evaluate(intervalFraction, mFirstKeyframe.getValue(),
nextKeyframe.getValue());
} else if (fraction >= 1f) {
final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2);
final TimeInterpolator interpolator = mLastKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
final float prevFraction = prevKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) /
(mLastKeyframe.getFraction() - prevFraction);
return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
mLastKeyframe.getValue());
}
Keyframe prevKeyframe = mFirstKeyframe;
for (int i = 1; i < mNumKeyframes; ++i) {
Keyframe nextKeyframe = mKeyframes.get(i);
if (fraction < nextKeyframe.getFraction()) {
final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
final float prevFraction = prevKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) /
(nextKeyframe.getFraction() - prevFraction);
// Apply interpolator on the proportional duration.
if (interpolator != null) {
intervalFraction = interpolator.getInterpolation(intervalFraction);
}
return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
nextKeyframe.getValue());
}
prevKeyframe = nextKeyframe;
}
// shouldn't reach here
return mLastKeyframe.getValue();
}
在这之前有一个方法:
void calculateValue(float fraction) {
Object value = mKeyframes.getValue(fraction);
mAnimatedValue = mConverter == null ? value : mConverter.convert(value);
}
调用到了getValue(),得到的值放在了mAnimatedValue里面,要通过PropertyValuesHolder类的getAnimatedValue()函数来得这个值
而这个函数在ValusAnimator中有调用。
void animateValue(float fraction) {
fraction = mInterpolator.getInterpolation(fraction);
mCurrentFraction = fraction;
int numValues = mValues.length;
for (int i = 0; i < numValues; ++i) {
mValues[i].calculateValue(fraction);
}
if (mUpdateListeners != null) {
int numListeners = mUpdateListeners.size();
for (int i = 0; i < numListeners; ++i) {
mUpdateListeners.get(i).onAnimationUpdate(this);
}
}
}
Android系统内置了很多的估值器:
如下几种估值器 ArgbEvaluator, FloatArrayEvaluator, FloatEvaluator, IntArrayEvaluator, IntEvaluator, PointFEvaluator, RectEvaluator。
当然我们也可以自定义估值器,比我我们自定义一个实现字符从A_Z变化的估值器。
public class CalEvaluator implements TypeEvaluator<character> {
@Override
public Character evaluate(float fraction, Character startValue, Character endValue) {
int startInt = (int) startValue;
int endInt = (int) endValue;
int cur = (int) (startInt + fraction * (endInt - startInt));
return (char) cur;
}
}
代码链接:点击打开链接
android动画之interpolator和typeEvaluator用法详解的更多相关文章
- Android GLSurfaceView用法详解(二)
输入如何处理 若是开发一个交互型的应用(如游戏),通常需要子类化 GLSurfaceView,由此可以获取输入事件.下面有个例子: java代码: package eoe.ClearTes ...
- Android Fragment用法详解(2)--动态添加Fragment
在上一篇文章<Android Fragment用法详解(1)--静态使用Fragment>我们讲解了Fragment的最简单的用法.这次我们来说一说Fragment复杂一丢丢的用法.在代码 ...
- CSS3的@keyframes用法详解:
CSS3的@keyframes用法详解:此属性与animation属性是密切相关的,关于animation属性可以参阅CSS3的animation属性用法详解一章节. 一.基本知识:keyframes ...
- 1:CSS中一些@规则的用法小结 2: @media用法详解
第一篇文章:@用法小结 第二篇文章:@media用法 第一篇文章:@用法小结 这篇文章主要介绍了CSS中一些@规则的用法小结,是CSS入门学习中的基础知识,需要的朋友可以参考下 at-rule ...
- Android ADB命令教程二——ADB命令详解
Android ADB命令教程二——ADB命令详解 转载▼ 原文链接:http://www.tbk.ren/article/249.html 我们使用 adb -h 来看看,adb命令里面 ...
- Android进阶笔记:Messenger源码详解
Messenger可以理解为一个是用于发送消息的一个类用法也很多,这里主要分析一下再跨进程的情况下Messenger的实现流程与源码分析.相信结合前面两篇关于aidl解析文章能够更好的对aidl有一个 ...
- Android逆向之旅---SO(ELF)文件格式详解(转)
第一.前言 从今天开始我们正式开始Android的逆向之旅,关于逆向的相关知识,想必大家都不陌生了,逆向领域是一个充满挑战和神秘的领域.作为一名Android开发者,每个人都想去探索这个领域,因为一旦 ...
- Vue1.0用法详解
Vue.js 不支持 IE8 及其以下版本,因为 Vue.js 使用了 IE8 不能实现的 ECMAScript 5 特性. 开发环境部署 可参考使用 vue+webpack. 基本用法 1 2 3 ...
- Android消息传递之EventBus 3.0使用详解
前言: 前面两篇不仅学习了子线程与UI主线程之间的通信方式,也学习了如何实现组件之间通信,基于前面的知识我们今天来分析一下EventBus是如何管理事件总线的,EventBus到底是不是最佳方案?学习 ...
随机推荐
- git使用之错误分析及解决(持续更新)
错误一: 使用 $ git push -u origin master 出现如下错误: error: src refspec master does not match any. error: fai ...
- PHP 5 Math 函数
PHP Math 简介 Math 函数能处理 integer 和 float 范围内的值. 安装 PHP Math 函数是 PHP 核心的组成部分.无需安装即可使用这些函数. PHP 5 Math 函 ...
- PHP XML SimpleXML
PHP 可以基于 SimpleXML 生成和解析 xml 的方法,通过本节的实例,你将了解 PHP 是如何使用 SimpleXML 生成及解析 xml 格式数据的. PHP SimpleXML 处理最 ...
- PHP Zip File 函数
通过 PHP 中的相关函数,你可以实现 zip 文件的解压缩操作! PHP Zip File 简介 Zip File 函数允许您读取压缩文件. 安装 如需在服务器上运行 Zip File 函数,必须安 ...
- Bootstrap3 排版-页面主体
Bootstrap 将全局 font-size 设置为 14px,line-height 设置为 1.428.这些属性直接赋予 元素和所有段落元素.另外,<p> (段落)元素还被设置了等于 ...
- Ajax PHP JavaScript MySQL实现简易的无刷新在线聊天室
思路 消息显示区 发消息 板块 消息显示 消息发送 优化 显示非重复性的数据 优化显示 加上滚动条 每次都显示最新消息 完整代码 前端代码 数据库表结构 服务器端代码 总结与展望 总结 展望 为更好的 ...
- 打开CMDLINE中的 ” earlyprink “ 参数
点击打开链接 解决问题的过程中,好文章推荐,都保存在火狐wilson_sq@qq.com记录中~~~~~~~~grep -r "earlyprintk" kernelkernel/ ...
- protobuf中的枚举缺省值应该为UNKNOWN
protobuf中的枚举缺省值应该为UNKNOWN(金庆的专栏)proto3中的枚举值为了与proto2兼容,要求缺省值固定为第1个,值为0.proto2中并没有规定对范围之外的枚举值的处理,而pro ...
- 物料分类新增&更新
--新增 INV_ITEM_CATEGORY_PUB.Create_Category ( p_api_version IN NUMBER, p_init_msg_list IN VARCHAR2 DE ...
- Linux Java开发坏境搭建,Ubuntu-jdk+tomcat+eclipse+svn 包安装详细操作
更新时间2015-03-15 更新2015-04-12 svn安装更新 第一步 安装jdk (在linux上使用yum安装JDK http://blog.chinaunix.net/uid-1546 ...