android动画之interpolator和typeEvaluator用法详解手机开发
我们在写动画的时候为了达到某种效果往往需要设置插值器,用来真实的模拟生活中的场景。
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; // shouldnt 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; }
代码链接:点击打开链接
5667.html
app程序应用开发手机开发无线开发移动端开发相关文章
- Android 开机动画的制作「建议收藏」
- android定时器取消,Android定时器崩溃取消
- android-短信验证功能,Android实现获取短信验证码的功能以及自定义GUI短信验证详解…
- android 验证码短信验证码,Android短信验证码倒计时验证的2种常用方式
- android toast全屏,Android Toast实现全屏显示
- Android resource linking failed_android:authorities
- android toast 自定义时间,Android 自定义 Toast 显示时间「建议收藏」
- android触摸屏事件,Android Touch事件分析
- android应用程序_chrome Android
- Android开发笔记(一百八十七)利用估值器实现弹幕动画
- Android resource linking failed_android sdk location should not
- 【错误记录】Android Studio 编译报错 ( Invalid main APK outputs : EarlySyncBuildOutput )
- 【Android UI】Paint Gradient 渐变渲染 ③ ( RadialGradient 环形渐变渲染 | 在给定中心和半径的情况下绘制径向渐变的着色器 | 水波纹效果 )
- H5-vue与原生Android、ios交互获取相册图片
- Android实现ProgressBar旋转菊花加载的动画详解手机开发
- Android动画深入分析详解手机开发
- android版本检测Android程序的版本检测与更新实现介绍
- Android动画之3D翻转效果实现函数分析
- Android设置应用全屏的两种解决方法
- android如何添加桌面图标和卸载程序后自动删除图标