属性动画之ValueAnimator

原创 2016年06月01日 16:50:11
    ValueAnimator是属性动画中的一个重要的类,其内部使用一种时间循环的机制来计算值与值之间的动画过渡,我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。ObjectAnimator其实就是ValueAnimator的一个子类,之所以先了解ObjectAnimator<<属性动画之ObjectAnimator>>,是因为ObjectAnimator用的比较多,功能完善,比较直观,容易理解,而ValueAnimator一般在自定义一些复杂的动画时会使用。
    ValueAnimator的使用与ObjectAnimator类似,也提供了一些ofXXX方法,先看一个简单的例子,
private void animation() {
    ValueAnimator animator = ValueAnimator.ofFloat(0f, 350f, 0f );
    animator.setDuration(2000);
    animator.setTarget(head);
    animator.setRepeatCount(Animation.INFINITE);
    animator.start();
}
    执行这段代码后,发现没有什么变化,这一点也不奇怪,因为我们没有设定操作对象的属性,系统肯定不知道该如何处理了。那如何设置属性呢?但我们发现ValueAnimator的ofXXX方法中没有设置属性的参数,也没用setXXX方法,那就先放一边。
    在讲解ObjectAnimator这块内容时,有说过AnimatorUpdateListener这个接口,可以读取到动画的每个更新值,当前的例子在界面上没有任何现象,那这个更新值是否在变化呢?尝试加上这个接口,打印动画的值,
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
        Log.d("dingfeng", "animation value:"+(float)animation.getAnimatedValue());
    }
});
打印log,
06-01 11:15:59.819 20681-20681/? D/dingfeng: animation value:260.29874
06-01 11:15:59.839 20681-20681/? D/dingfeng: animation value:269.3637
06-01 11:15:59.859 20681-20681/? D/dingfeng: animation value:278.48615
06-01 11:15:59.869 20681-20681/? D/dingfeng: animation value:287.6596
06-01 11:15:59.889 20681-20681/? D/dingfeng: animation value:296.8775
06-01 11:15:59.909 20681-20681/? D/dingfeng: animation value:305.58807
06-01 11:15:59.929 20681-20681/? D/dingfeng: animation value:314.87332
06-01 11:15:59.939 20681-20681/? D/dingfeng: animation value:324.1839
06-01 11:15:59.959 20681-20681/? D/dingfeng: animation value:333.51276
06-01 11:15:59.979 20681-20681/? D/dingfeng: animation value:342.85336
06-01 11:15:59.989 20681-20681/? D/dingfeng: animation value:347.80093
06-01 11:16:00.009 20681-20681/? D/dingfeng: animation value:338.45682
我们可以看到动画的值是更新的,那就可以可以根据这个值来自己设置操作的对象的属性,比如水平移动,
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
        Log.d("dingfeng", "animation value:"+(float)animation.getAnimatedValue());
        head.setTranslationX((float)animation.getAnimatedValue());
    }
});

    这样也达到了水平移动的效果,看似也比较简单。
    ValueAnimator也是可以设置任意属性的,使用ofObject方法,在此之前我们需要先了解TypeEvaluator的使用。
TypeEvaluator
    ofObject()方法和ofInt(),ofFloat()不同,需要自己实现TypeEvaluator,而其他两个方法系统内部都帮忙实现了其方法,分别是IntEvaluator和FloatEvaluator类型,那就看一下FloatEvaluator时如何实现的。
public class FloatEvaluator implements TypeEvaluator<Number> {

/**
     * This function returns the result of linearly interpolating the start and end values, with
     * <code>fraction</code> representing the proportion between the start and end values. The
     * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
     * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
     * and <code>t</code> is <code>fraction</code>.
     *
     * @param fraction   The fraction from the starting to the ending values
     * @param startValue The start value; should be of type <code>float</code> or
     *                   <code>Float</code>
     * @param endValue   The end value; should be of type <code>float</code> or <code>Float</code>
     * @return A linear interpolation between the start and end values, given the
     *         <code>fraction</code> parameter.
     */
    public Float evaluate(float fraction, Number startValue, Number endValue) {
         float startFloat = startValue.floatValue();
         return startFloat + fraction * (endValue.floatValue() - startFloat);
    }
}
    可以看到,FloatEvaluator实现了TypeEvaluator接口,然后重写evaluate()方法。evaluate()方法当中传入了三个参数,第一个参数fraction非常重要,这个参数用于表示动画的完成度的(fraction的值在0~1之间变化),我们应该根据它来计算当前动画的值应该是多少,第二第三个参数分别表示动画的初始值和结束值。那么上述代码的逻辑就比较清晰了,用结束值减去初始值,算出它们之间的差值,然后乘以fraction这个系数,再加上初始值,那么就得到当前动画的值了。
    现在看这样一个例子,让左上角的图片沿着屏幕四周滑动,最后回到左上角。
    考虑动画的整个过程,左上角-->左下角-->右下角-->右上角-->左上角,一共四个过程,每两个角直接就是一个过程,那我们应该要知道四个角的坐标(PonitF)
// 先设定屏幕四个角的坐标,注意空间的宽高和状态栏的高度
PointF start = new PointF(0, 0);
PointF point1 = new PointF(0, screenHeight - imgHeight - statusBarHeight);
PointF point2 = new PointF(screenWidth - imgWidth, screenHeight - imgHeight - statusBarHeight);
PointF point3 = new PointF(screenWidth - imgWidth, 0);
PointF end = new PointF(0, 0);
    然后就要计算滑动过程中的坐标值,这个时候就要自定义一个TypeEvaluator,实现evaluate,上面已经对该方法进行了解释,那我们这里就很容易处理了。比如,
x的坐标值 = 初始值 + (结束值 - 初始值)* 完成度,然后同样的方式计算得出y的坐标值,最后生成新坐标,
ValueAnimator animator2 = ValueAnimator.ofObject(new TypeEvaluator<PointF>() {
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
// 计算滑动过程中的水平和垂直距离,生成新的坐标
float x = startValue.x + fraction * (endValue.x - startValue.x);
float y = startValue.y + fraction * (endValue.y - startValue.y);
PointF point = new PointF(x, y);
return point;
    }
}, start, point1, point2, point3, end);
    实现AnimatorUpdateListener接口,读取到动画的每个更新值,将动画值转化为坐标,设置操作对象的x和y值,这样位置就更新了。
animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
    // 将动画值转化为为PointF对象,然后更新空间的位置
    PointF current = (PointF) animation.getAnimatedValue();
    head.setX(current.x);
    head.setY(current.y);
    }
});

   当然,我们这里实现的TypeEvaluator也还是比较简单的,真正复杂的动画效果要编写一个TypeEvaluator还是要花一些精力的。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

ValueAnimator属性动画

1 官方文档This class provides a simple timing engine(计时器) for running animations which calculate animate...

Android 属性动画ValueAnimator和ObjectAnimator的高级用法

尊重版权,转载请声明出处:http://blog.csdn.net/guolin_blog/article/details/43816093 大家好,在上一篇文章当中,我们学习了Androi...

Android属性动画(二):深入valueAnimator和objecAnimator

ValueAnimator的高级用法 无论是valueAnimator还是objectAnimator都离不开TypeEvaluator的使用,那TypeEvaluator是用来干嘛的? Type...

Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 大家好,在上一篇文章当中,我们学习了Android属性动画的基...

Android开发 之 属性动画(自定义ValueAnimator的TypeEvaluator)

自定义ValueAnimator的TypeEvaluator 翻译过来就是类型计算器,对,就是一个计算器,只不过这计算器的计算规则由你设定,也就是你要继承重写喽。 对于valueAnimator...

Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法

转载地址:http://blog.csdn.net/guolin_blog/article/details/43816093 目录(?)[-] ValueAnimator的...

属性动画01-ValueAnimator(数值产生器)

写代码尴尬的是类太多不知道应该使用哪一个,正确的说是不知道某个类是做什么的.所以比较喜欢从源头看一下,有个大致了解.属性动画需要了解的 补间动画需要了解的 属性动画与3.0之前的一个对比因为主...

Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,...

Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法

大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了。但是,正如上篇文章当中所说到的,属性动画对补间动画进行了...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)