Android动画学习笔记(二)——动画插值器Interpolator
来源:互联网 发布:深入解析wpf编程 编辑:程序博客网 时间:2024/06/03 15:40
前言:上篇博客我们对补间动画的xml及代码生成做了简单的介绍,今天我们来讲讲动画的一个核心类Interpolator插值器,对于数学好的童鞋来说,学习本节内容就soeasy了!(ps:本人数学很差,都忘光了(^__^) ),废话不多说,让我们一起开动吧。
1、What?(什么是Interpolator?)
/** * An interpolator defines the rate of change of an animation. This allows * the basic animation effects (alpha, scale, translate, rotate) to be * accelerated, decelerated, repeated, etc. */public interface Interpolator extends TimeInterpolator { // A new interface, TimeInterpolator, was introduced for the new android.animation // package. This older Interpolator interface extends TimeInterpolator so that users of // the new Animator-based animations can use either the old Interpolator implementations or // new classes that implement TimeInterpolator directly.}
英文不好,大致翻译一下“插值器就是一个动画变化 的速率,可以让一些基础的动画如(透明、缩放、平移、旋转)加速、减速、重复性等…”
2、why?(Interpolator为什么可以让一些基础的动画如(透明、缩放、平移、旋转)加速、减速、重复性等…)
我们跟着源码撸一遍代码
Interpolator<–TimeInterpolator,我们看到,Interpolator除了实现了TimeInterpolator外什么都行没干,于是我们看看TimeInterpolator。
public interface TimeInterpolator { /** * Maps a value representing the elapsed fraction of an animation to a value that represents * the interpolated fraction. This interpolated value is then multiplied by the change in * value of an animation to derive the animated value at the current elapsed animation time. * * @param input A value between 0 and 1.0 indicating our current point * in the animation where 0 represents the start and 1.0 represents * the end * @return The interpolation value. This value can be more than 1.0 for * interpolators which overshoot their targets, or less than 0 for * interpolators that undershoot their targets. */ float getInterpolation(float input);}
TimeInterpolator 也很简单,只有一个方法getInterpolation,“将动画执行的过程值(0-1.0f)经过我们插值器处理,然后获取一个新的值,当然也可以不处理原样返回,比如(LinearInterxpolator).”
3、How ?(Interpolator怎么工作,以及怎么使用它)
我们在Animation的源码中看到这个一个代码:
public boolean getTransformation(long currentTime, Transformation outTransformation) { if (mStartTime == -1) { mStartTime = currentTime; } .....省略很多代码 final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime); .....省略很多代码 }
这个方法就是:传入一个当前时间,然后获取当前动画执行的位置
那么getTransformation又是谁调用的呢?我们知道,当我们执行一个动画的时候,我们view.startAnimation(anim)就可以了–>然后view就会调用其invalidate使其重绘–>view调用draw方法重新绘制view–>在draw方法中判断如果有动画的话会执行applyLegacyAnimation方法—>执行动画的a.getTransformation方法—>
下面是View的onDraw方法中的一段代码:
final Animation a = getAnimation(); if (a != null) { more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired); concatMatrix = a.willChangeTransformationMatrix(); if (concatMatrix) { mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM; } transformToApply = parent.getChildTransformation(); }
—>在applyLegacyAnimation方法中我们看到:
a.getTransformation(drawingTime, invalidationTransform, 1f);
—>尼玛,走了半天终于到我们动画方法里面来了,我们看到在Animation中的getTransformation方法:
public boolean getTransformation(long currentTime, Transformation outTransformation) { ///省略代码 final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime); applyTransformation(interpolatedTime, outTransformation); ///省略代码 }
—->经过Animation的getTransformation方法,然后我们看到一个叫interpolatedTime 的数据,也就是经过插值器处理过的动画执行到哪的一个位置值—->最后给了applyTransformation方法。
protected void applyTransformation(float interpolatedTime, Transformation t) { }
也就是说,ScaleAnimation、RotateAnimation….只需要重写applyTransformation方法,然后对Transformation 中的值进行操作,最后返回到view的draw方法中。
尼玛!!!我们把动画的原理都整个跑了一遍了,小伙伴应该明白动画的原理的吧,不懂没关系,多跑几遍源码就可以啦^_^,同样,插值器怎么工作的应该也明白。
最后我们怎么用插值器呢?
//new 一个插值器,然后设置给动画类就可以了scaleAnimation.setInterpolator((Interpolator) obj);
Android api中自带有几个插值器,它们分别是:
- AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
- AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
- AnticipateInterpolator 开始的时候向后然后向前甩
- AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
- BounceInterpolator 动画结束的时候弹起
- CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
- DecelerateInterpolator 在动画开始的地方快然后慢
- LinearInterpolator 以常量速率改变
- OvershootInterpolator 向前甩一定值后再回到原来位置
在xml中可以这样使用:
android:interpolator=@android:anim/accelerate_decelerate_interpolator
在java代码中直接创建即可:
AnimationSet set = new AnimationSet(true); set.setInterpolator(new AccelerateDecelerateInterpolator());
其实吧,这些插值器也都是一些算法,将平滑的0-0.1f范围中的值,进行输入输出转变,接下来我们结合图像一个一个分析一下:
AccelerateDecelerateInterpolator(在动画开始与结束的地方速率改变比较慢,在中间的时候加速)
对象坐标图:2.AccelerateInterpolator(在动画开始的地方速率改变比较慢,然后开始加速)
3、AnticipateInterpolator(开始的时候向后然后向前甩)
4、AnticipateOvershootInterpolator开始的时候向后然后向前甩一定值后返回最后的值
5、BounceInterpolator(动画结束的时候弹起)
6、CycleInterpolator(动画循环播放特定的次数,速率改变沿着正弦曲线)
7、DecelerateInterpolator(在动画开始的地方快然后慢)
8、LinearInterpolator(以常量速率改变)
9、OvershootInterpolator(向前甩一定值后再回到原来位置)
好啦!!系统自带的插值器我们是介绍完了,小伙伴们有没有点感觉了呢?
我们以LinearInterpolator插值器为例:
@HasNativeInterpolatorpublic class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { public LinearInterpolator() { } public LinearInterpolator(Context context, AttributeSet attrs) { } public float getInterpolation(float input) { return input; } /** @hide */ @Override public long createNativeInterpolator() { return NativeInterpolatorFactoryHelper.createLinearInterpolator(); }}
可见,LinearInterpolator是以常量的方式原样返回了input(物理好的同学说,是不是可以看做匀速直线运动呢?(^__^) 嘻嘻……)
当然,也可以自己定义一个插值器,然后重写下getInterpolation,对input进行处理即可。
说了这么多,我们都还没有实战过的,下面我们围绕旋转动画对各个插值器做一下效果对比(也可以直接拖我的github链接demo查看,链接最后会给出):
我们创建一个从0旋转到360度的Translate动画:
private RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
1、AccelerateDecelerateInterpolator(在动画开始与结束的地方速率改变比较慢,在中间的时候加速)
2、AccelerateInterpolator(在动画开始的地方速率改变比较慢,然后开始加速)
3、AnticipateInterpolator(开始的时候向后然后向前甩)
4、AnticipateOvershootInterpolator(开始的时候向后然后向前甩一定值后返回最后的值)
5、BounceInterpolator(动画结束的时候弹起)
6、CycleInterpolator(动画循环播放特定的次数,速率改变沿着正弦曲线)
7、DecelerateInterpolator(在动画开始的地方快然后慢)
8、LinearInterpolator(以常量速率改变)
9、OvershootInterpolator(向前甩一定值后再回到原来位置)
还有几个动画的测试我就直接上效果图了,要研究的童鞋我最后会给github链接。
AlphaAnimation插值器测试:
RotateAnimation插值器测试:
ScaleAnimation插值器测试:
好啦!!插值器部分就到这里了,喜欢的小伙伴几个点个赞哈。
github链接https://github.com/913453448/AnDemo
- Android动画学习笔记(二)——动画插值器Interpolator
- Animation动画详解(二)——Interpolator插值器
- Animation动画详解(二)——Interpolator插值器
- Android动画--Interpolator(插值器)
- Android 动画 Interpolator插值器
- android Interpolator动画插值器
- 动画——Interpolator插值器
- Android属性动画Interpolator(插值器)
- Android 动画之二 View Animation —— 补间(Tween)动画与Interpolator的介绍
- Android Easing Interpolator——一些动画插值器
- android 动画的Interpolator插值器
- Android动画-Interpolator(插值器)大全
- Android自定义动画插值器Interpolator
- android 动画的Interpolator插值器
- Android动画之Interpolator(插值器)
- android动画(一)Interpolator
- android动画(一)Interpolator
- android动画(一)Interpolator
- 34-2-2
- URL,URI以及ServletPath的区别
- 测试地址通不通:ping / telnet / wget / traceroute
- 程序设计入门——C语言 翁恺 第5周编程练习
- 各种时间格式的转换
- Android动画学习笔记(二)——动画插值器Interpolator
- OCX控件的注册卸载,以及判断是否注册
- Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailab
- 数据库编程入门(一)-PL/SQL快速入门
- mybatis mapper代理以及与spring集成
- ROS control-----hardware_interface简介
- STM32L1学习笔记01 工先利其器之CoIDE
- Latex 使用windows自带字体
- Oracle视图走索引