前言:唯有脚踏实地,才能厚积薄发,未来只属于为梦想而奋斗的人们,今天的你决定未来的自己。
相关文章:
《Android自定义控件三部曲文章索引》:http://blog.csdn.net/harvic880925/article/details/50995268
上一篇给大家介绍了ValueAnimator的大部分函数的用法,不过还都是些简单的用法,这篇我们带大家来看看有关加速器、animator和keyFrame的知识。
一、插值器
插值器,也叫加速器;有关插值器的知识,我在《Animation动画详解(二)——Interpolator插值器》中专门讲过,大家可以先看看这篇文章中各个加速器的效果。
这里再讲一下什么是插值器。我们知道,我们通过ofInt(0,400)定义了动画的区间值是0到400;然后通过添加AnimatorUpdateListener来监听动画的实时变化。那么问题来了,0-400的值是怎么变化的呢?像我们骑自行车,还有的快有的慢呢;这个值是匀速变化的吗?如果是,那我如果想让它先加速再减速的变化该怎么办?
这就是插值器的作用!插值器就是用来控制动画区间的值被如何计算出来的。比如LinearInterpolator插值器就是匀速返回区间点的值;而DecelerateInterpolator则表示开始变化快,后期变化慢;其它都类似,下面我们就看看ValueAnimator中插值器的应用方法,然后通过自定义一个插值器来看看插值器到底是什么。
1、使用插值器
我们就以BounceInterpolator(弹跳插值器)为例做一个实验,BounceInterpolator的解释是动画结束的时候弹起;我们来看一下效果:
下面我们就来看一下利用ValueAnimator是如何实现的。布局和上一篇的都一样,这里就不再细讲了,我们着重来看一下,当点击start anim按钮以后是怎么做的,代码如下:
ValueAnimator animator = ValueAnimator.ofInt(0,600);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = (int)animation.getAnimatedValue();
tv.layout(tv.getLeft(),curValue,tv.getRight(),curValue+tv.getHeight());
}
});
animator.setDuration(1000);
animator.setInterpolator(new BounceInterpolator());
animator.start();
如果大家已经看懂了上篇,这段代码就非常容易理解了,在监听中,我们只改变textview的top和bottom的位置,让它跟着当前动画的值来改变它当前的top和bottom的位置。然后我们利用setDuration(1000)给它设置上做一次动画所需要的时长,然后通过setInterpolator()给它设置插值器,也就是过渡值变化的规则;
从效果图中也可以看出,插值器的意义其实就相当于物理公式中的加速度参数,所以这也就是它也叫加速器的原因。
源码在文章底部给出
在学会了怎么使用加速器以后,我们来看看如何自定义一个加速器吧
2、自定义加速器
1、概述
在这段,我们就开始着手自己写一个加速器了,在写加速器之前,先看看人家的加速器是怎么写的吧。
先看看LinearInterpolator:
public class LinearInterpolator implements Interpolator {
public LinearInterpolator() {
}
public LinearInterpolator(Context context, AttributeSet attrs) {
}
public float getInterpolation(float input) {
return input;
}
}
public interface Interpolator extends TimeInterpolator {
}
LinearInterpolator实现了Interpolator接口;而Interpolator接口则直接继承自TimeInterpolator,而且并没有添加任何其它的方法。
那我们来看看TimeInterpolator接口都有哪些函数吧:
/**
* A time interpolator defines the rate of change of an animation. This allows animations
* to have non-linear motion, such as acceleration and deceleration.
*/
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的代码,它里面只有一个函数float getInterpolation(float input);我们来讲讲这个函数是干什么的。
参数input:input参数是一个float类型,它取值范围是0到1,表示当前动画的进度,取0时表示动画刚开始,取1时表示动画结束,取0.5时表示动画中间的位置,其它类推。
返回值:表示当前实际想要显示的进度。取值可以超过1也可以小于0,超过1表示已经超过目标值,小于0表示小于开始位置。
对于input参数,它表示的是当前动画的进度,匀速增加的。什么叫动画的进度,动画的进度就是动画在时间上的进度,与我们的任何设置无关,随着时间的增长,动画的进度自然的增加,从0到1;input参数相当于时间的概念,我们通过setDuration()指定了动画的时长,在这个时间范围内,动画进度肯定是一点点增加的;就相当于我们播放一首歌,这首歌的进度是从0到1是一样的。
而返回值则表示动画的数值进度,它的对应的数值范围是我们通过ofInt(),ofFloat()来指定的,这个返回值就表示当前时间所对应的数值的进度。
我们先看看下面这段代码ÿ