Android学习笔记(九)| Android动画(下)—— 属性动画

参考书籍:《Android开发艺术探索》 任玉刚
如有错漏,请批评指出!

属性动画是API 11 新加入的特性,不同于View动画只能作用于View,它可以对任意对象做动画操作。比较常用的几个动画类有 ValueAnimator、ObjectAnimator、AnimatorSet,想要兼容API 11 以前的Android版本,我们可以使用开源动画库 nineoldandroids,这里就不去探讨它的使用方法了,下面我们来看属性动画的用法。

属性动画的用法

属性动画可以对任意对象的属性进行动画而不仅仅是View,动画默认时间是300ms,默认帧率是 10ms/帧。先来看看ValueAnimator 和 ObjectAnimator 这两个类:

ValueAnimator

ValueAnimator 这个类本身不作用于任何对象,它是在一定时间内对一个值进行平滑过渡,因此,我们要使用它来实现动画,就需要监听这个过渡过程,获取过渡值,利用这个过渡值来对实际的对象进行处理(可能不太好理解)。下面来看看代码:

ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 1000.0f);
animator.setDuration(100);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        Log.e("code", animation.getAnimatedValue()+"");
    }
});
animator.start();

先来看打印结果:
Android学习笔记(九)| Android动画(下)—— 属性动画_第1张图片

可以看到,这里实现的是在100ms内将一个数从1.0变为1000.0,每一帧(即每更新一次数值)会回调一次 onAnimationUpdate() 方法,在这个方法中,我们可以通过传入的 ValueAnimation 对象的 getAnimatedValue() 方法获取这个值,利用这个值来实现动画效果。

当然,还有更简单的方法,我们重点来看 ObjectAnimator 类。

ObjectAnimator

ObjectAnimator 类 是继承自 ValueAnimator 类的,它主要重写了 ValueAnimator 的几个 ofXXX() 方法,让动画与对象直接相关联,这样我们就不需要自己来监听动画过程,控制动画效果了。下面来看几个示例:
注:下面的代码中涉及到一些基本属性,在 Android学习笔记(七)| Android动画(上)—— View动画 中已经讲过,没看过的话,建议移步。

  • 实现平移、旋转、缩放、透明度动画
        // translationX —— 在 X 轴方向平移 translationY —— 在 Y 轴方向平移
        ObjectAnimator translateAnimator = ObjectAnimator.ofFloat(tvObjAnim, "translationX", 0.0f, 200.0f);
        translateAnimator.setDuration(1000);
        translateAnimator.setRepeatMode(ValueAnimator.REVERSE);
        translateAnimator.setRepeatCount(ValueAnimator.INFINITE);
        translateAnimator.start();
    
        // rotationX —— 以水平中心线为轴旋转  rotationY —— 以竖直中心线为轴旋转
        ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(tvRotate, "rotationX", 0, 180);
        rotateAnimator.setDuration(1000);
        rotateAnimator.setRepeatMode(ValueAnimator.REVERSE);
        rotateAnimator.setRepeatCount(ValueAnimator.INFINITE);
        rotateAnimator.start();
    
        // scaleX —— 以中心为缩放轴点横向缩放 scaleY —— 以中心为缩放轴点竖直缩放
        ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(tvScale, "scaleX", 1.0f, 2.0f);
        scaleAnimator.setDuration(1000);
        scaleAnimator.setRepeatMode(ValueAnimator.REVERSE);
        scaleAnimator.setRepeatCount(ValueAnimator.INFINITE);
        scaleAnimator.start();
    
        // alpha —— 改变透明度
        ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(tvAlpha, "alpha", 1, 0);
        alphaAnimator.setDuration(1000);
        alphaAnimator.setRepeatMode(ValueAnimator.REVERSE);
        alphaAnimator.setRepeatCount(ValueAnimator.INFINITE);
        alphaAnimator.start();
    
  • 实现颜色渐变
        ObjectAnimator animator = ObjectAnimator.ofInt(tvColor, "backgroundColor", 0xff689f38, 0xff34a2da);
        animator.setDuration(3000);
        // 设置针对Color属性的估值器
        animator.setEvaluator(new ArgbEvaluator());
        animator.setRepeatMode(ValueAnimator.REVERSE);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.start();
    
    这里涉及到一个插值器的概念,后面会讲到。这段代码实现的效果就是在3s内将View的颜色从 #689f38 渐变为 #34a2da , 并且重复模式是逆转,无限循环。
AnimatorSet

AnimatorSet 是动画集合,也就是同时播放一组动画。

    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.playTogether(
        ObjectAnimator.ofFloat(tvObjAnim, "translationX", 0.0f, 200.0f), 
        ObjectAnimator.ofFloat(tvRotate, "rotationX", 0, 180),
        ObjectAnimator.ofFloat(tvScale, "scaleX", 1.0f, 2.0f),
        ObjectAnimator.ofFloat(tvAlpha, "alpha", 1, 0)
    );
    animatorSet.setDuration(1000);
    animatorSet.start();

想要让动画循环播放的话,还是需要给每个ObjectAnimator单独指定相关属性。

上面这些效果都可以通过 xml 来定义,在前面的文章也讲过xml定义,只是标签不同,这里就不赘述了。

  • 标签 对应 ValueAnimator 类
  • 标签 对应 ObjectAnimator 类
    propertyName:表示作用对象的属性的名称(translationX、rotationX等)
    valueType属性有两个可选值:intType——整型,floatType——浮点型。
    注意:当 propertyName 指定为颜色相关属性时,不需要指定 valueType 属性,系统会自动对颜色类型的属性做处理。
  • 标签 对应 AnimatorSet 类
    ordering 属性有两个可选值:together——子动画同时播放,sequentially——子动画按顺序依次播放。

插值器 和 估值器 的概念

  • TimeInterpolator 翻译为时间插值器,它的作用是根据当前时间流逝的百分比来计算当前属性值改变的百分比,系统预置了 LinearInterpolator(线性插值器:匀速动画)、AccelerateDecelerateInterpolator(加速减速插值器:动画两头慢中间快) 和 DecelerateInterpolator(减速插值器:动画越来越慢)等。
  • TypeEvaluator 翻译为估值器,它的作用是根据 TimeInterpolator 计算出的属性改变百分比来计算当前时间节点的属性值,系统预置有 IntEvaluator(针对整型属性)、FloatEvaluator(针对浮点型属性)和ArgbEvaluator(针对 Color 属性)。

属性动画的监听器

属性动画提供了监听器用于监听动画的播放过程,主要有两个接口:AnimatorUpdateListener 和 AnimatorListener。

  • AnimatorListener
    接口定义如下:
    public static interface AnimatorListener {
        default void onAnimationStart(Animator animation, boolean isReverse) {
            onAnimationStart(animation);
        }

        default void onAnimationEnd(Animator animation, boolean isReverse) {
            onAnimationEnd(animation);
        }

        void onAnimationStart(Animator animation);

        void onAnimationEnd(Animator animation);

        void onAnimationCancel(Animator animation);

        void onAnimationRepeat(Animator animation);
    }

可以看到,AnimatorListener 可以监听动画的开始、结束、取消以及重复播放。

  • AnimatorUpdateListener
    接口定义:
    public static interface AnimatorUpdateListener {
        /**
         * 

Notifies the occurrence of another frame of the animation.

* * @param animation The animation which was repeated. */ void onAnimationUpdate(ValueAnimator animation); }

这个接口会监听动画的整个过程,前面说过动画是由许多帧组成的,也就是说,每播放一帧,onAnimationUpdate() 方法就会被调用一次。


上一篇:Android学习笔记(八)| Android动画(中)—— 帧动画
下一篇:Android学习笔记(十)| Drawable的基本用法

你可能感兴趣的:(Android学习笔记(九)| Android动画(下)—— 属性动画)