属性动画之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还是要花一些精力的。

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

Android 动画之属性动画ValueAnimator

  • 2016年11月04日 14:41
  • 70KB
  • 下载

Android中属性动画4----ValueAnimator拿到每一次变化的值

代码: Main4Activity package com.zhh.android; import android.animation.ValueAnimator; import android....

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

转载自:http://blog.csdn.net/guolin_blog/article/details/43536355 1.valueAnimator的高级用法 在上篇文章中介...

属性动画之—ValueAnimator基本使用

前言:不要让别人的无知断送了你的梦想,永远坚信你所坚信的。相关文章:《Android自定义控件三部曲文章索引》:http://blog.csdn.net/harvic880925/article/de...

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

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

Android属性动画(二)——ValueAnimator

前面我们了解了比较常用的ObjectAnimator,它继承自ValueAnimator,这篇我们研究属性动画最核心的一个类ValueAnimator。 属性动画的实现机制是通过对目标对象进行赋值并...

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

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 大家好,在上一篇文章当中,我们学习了Android属性动画的基...
  • dj0379
  • dj0379
  • 2016年05月18日 08:56
  • 624

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

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

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

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 大家好,在上一篇文章当中,我们学习了Android属性动画的基...
  • gjnm820
  • gjnm820
  • 2016年03月30日 11:19
  • 351

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

写代码尴尬的是类太多不知道应该使用哪一个,正确的说是不知道某个类是做什么的.所以比较喜欢从源头看一下,有个大致了解.属性动画需要了解的 补间动画需要了解的 属性动画与3.0之前的一个对比因为主...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:属性动画之ValueAnimator
举报原因:
原因补充:

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