Android动画系列之属性动画(Property Animation)详解

Android动画系列之属性动画(Property Animation)详解

1、简介

Property Animation官方链接

属性动画可以让任何对象加上动画效果。可以定义一个动画来改变任何对象属性,无论它是否显示在屏幕上。在指定的时间长度,属性动画改变属性值。通过指定对象属性来创造动画效果,比如View在屏幕上的位置,动画的时长,以及动画值的改变。

属性动画系统可以让定义一个动画的以下特征:

  • 持续时间(Duration):可以指定一个动画的持续时间。默认长度为300毫秒。
  • 时间插值器(Time interpolation):可以指定属性的值如何计算作为动画当前所用时间的函数。
  • 重复和行为(Repeat count and behavior):可以指定是否有一个动画重复时,达到持续时间的结束,有多少次重复动画。您还可以指定是否希望动画反向播放。设置它反向播放动画,然后反复重复,直到达到重复的数量。
  • 动画设置(Animator Sets):可以让动画成逻辑组,同时或顺序或在指定的延迟。
  • 帧刷新延迟(Frame refresh delay):可以指定如何经常刷新动画帧。默认设置为刷新每10毫秒,但应用程序可以刷新帧的速度最终取决于系统的整体是如何的,以及该系统可以为底层定时器服务的速度。 一般使用系统默认即可。

2、属性动画与补间动画的区别

补间动画只能作用于View对象,所以如果您想要作用于非View对象时,必须实现自己的代码。视图动画系统也受到限制,因为它只公开了View对象来动画,例如视图的缩放和旋转,而不是背景色。

补间动画的另一个缺点是它只修改了视图绘制的位置,而不是实际视图本身。例如,如果您动画一个按钮以在屏幕上移动,则该按钮的绘制正确,但是您可以单击该按钮的实际位置不会改变,因此您必须实现自己的逻辑来处理这个问题。

使用属性动画,这些约束将被完全解除,您可以对任何对象(视图和非视图)的任何属性进行动画化,并且对象本身实际上是被修改的。从更高层次上来说,您可以为要动画的属性(如颜色、位置或大小)添加动画,并可以定义动画的各个方面,如通过插值器或者多个动画的同步。

然而,补间动画需要更少的时间来设置,并且需要更少的代码来编写。如果补间动画完成了您需要做的所有事情,或者您的现有代码已经按照您想要的方式工作,则不需要使用属性动画系统。所以,根据不同场合来选择合适的动画,是最好的选择。

3、API概述

3.1、ValueAnimator

ValueAnimator API文档

这是整个属性动画的核心类,它封装了为动画设置起始值、结束值、持续时间以及如何重复等方法 ,当然还有监听变化值的回调方法。但是,ValueAnimator并没有将实时监听的变化值设置到目标对象的指定属性上,所以您必须手动设置。

3.1.1、ValueAnimator主要方法:
  • addUpdateListener(ValueAnimator.AnimatorUpdateListener listener):
  • getAnimatedValue():获取只有一个属性时的动画当前进行值
  • getAnimatedValue(String propertyName):根据属性名称获取当前的动画进行值
  • ofArgb(int… values):构造并返回在颜色值之间ValueAnimator对象
  • ofFloat(float… values):构造并返回在浮点值之间ValueAnimator对象
  • ofInt(int… values):构造并返回在整型之间ValueAnimator对象
  • ofObject(TypeEvaluator evaluator, Object… values):构造并返回在对象之间ValueAnimator对象
  • ofPropertyValuesHolder(PropertyValuesHolder… values):构造并返回在PropertyValuesHolder对象中指定的值之间的ValueAnimator对象,用于实现实现组合动画
3.1.2、ValueAnimator的使用

1、通过几个of方法获取ValueAnimator的实例,并设置属性的变化值开始与结束值;

2、设置动画的播放各种属性,如动画时长,是否循环等;

3、为动画设置监听addUpdateListener,在监听里面获取属性的变化值,将改变后的值赋给对象的属性值,然后刷新视图;

4、启动动画。

下面将通过改变button的宽度这个例子来演示:

/**
     * 将btn1的宽度由200px延展到800px
     */
    private void ofInt1(){
        //1、设置属性数值的初始值 & 结束值
        ValueAnimator valueAnimator = ValueAnimator.ofInt(200,800);

        //2:设置动画的播放各种属性
        valueAnimator.setDuration(3000);

        //3、添加监听
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                //获得每次变化后的属性值
                int currentValue = (int) animation.getAnimatedValue();

                //手动将变化的值赋给对象的属性
                btn1.getLayoutParams().width = currentValue;

                //刷新视图
                btn1.requestLayout();
            }
        });

        //4、启动动画
        valueAnimator.start();
    }

ValueAnimator.ofObject()的本质还是操作 * 值 *,只是是采用将 多个值 封装到一个对象里的方式 同时对多个值一起操作而已

3.2、ObjectAnimator

ObjectAnimator API文档链接

ObjectAnimator是ValueAnimator的子类,可以直接对对象的属性赋值进行操作。一般情况下都是使用ObjectAnimator。

想要正确的使用objectanimator更新属性,必须做到以下几点:

  • objectanimator 更新 动画的对象属性必须有一个setter函数的形式设置属性名。因为objectanimator依赖setter函数来自动更新动画,它必须能够与这个setter方法访问属性
    。例如想要修改一个属性width,必须存在setWidth方法。如果setter方法不存在,有三个选项:
    • 如果有权限则将setter方法添加到类中。
    • 使用您有权更改的包装类,并让该包装器使用有效的setter方法接收值,并将其转发给原始对象。
    • 使用ValueAnimator
  • 如果您在调用of方法创建动画时只传入了一个属性值(而不是既有启始值和终止值),那么系统将默认把这个值视为终止值,这就需要该属性包含getter()方法,以获得其初始值,getter()方法的命名规则与setter()方法一致
  • getter()方法获取值的类型与setter()方法设置值的类型必须相同
  • 实现动画的效果可能需要调用invalidate()方法强制view重绘,这需要在onAnimationUpdate()的回调方法中进行

ObjectAnimator的使用方法是类似ValueAnimator:

//第一个参数是需要设置动画的对象,第二个参数是需要改变的属性名称
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv1,"alpha",0f,1f);
        objectAnimator.setDuration(3000);
        objectAnimator.start();

常用的ObjectAnimator属性:

属性 作用 数值类型
alpha 控制透明度 float
rotation 控制旋转角度 float
translationX x方向的位移 float
translationX y方向的位移 float
scaleX X方向的缩放倍数 float
scaleY Y方向的缩放倍数 float
rotationX 以X轴为轴的旋转度数 float
rotationY 以Y轴为轴的旋转度数 float
3.3、AnimatorSet

AnimatorSet API文档链接

AnimatorSet播放一组Animator对象按指定的顺序排列。动画可以设置为一起播放,顺序,或在指定的延迟之后。、

AnimatorSet这个类提供了一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:

  • after(long delay):将现有动画延迟指定毫秒后执行
  • after(Animator anim):将现有动画插入到传入的动画之后执行
  • before(Animator anim):将现有动画插入到传入的动画之前执行
  • with(Animator anim):将现有动画和传入的动画同时执行
4、xml使用属性动画

在xml中一共可以使用三种标签:

  • ValueAnimator - animator
  • ObjectAnimator - objectAnimator
  • AnimatorSet - set

使用的时候在res/animator下新建xml文件

<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:ordering="sequentially">

    <animator
        android:duration="3000"
        android:startOffset="1000"
        android:valueFrom="200px"
        android:valueTo="800px"
        android:valueType="intType"/>

    <objectAnimator
            android:duration="2000"
            android:valueFrom="1"
            android:valueType="floatType"
            android:valueTo="0"
            android:propertyName="alpha"/>
set>

其中android:ordering=”sequentially”这个属性共有两个值:

  • sequentially:按顺序播放
  • together:同时播放

在代码中载入动画:


Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file);
animator.setTarget(view);
animator.start();
5、ViewGroup容器布局动画

属性动画系统提供了对ViewGroup对象进行动画化更改的功能,并提供了一种简单的方法来对视图对象本身进行动画化。
控件可以在ViewGroup中通过设置LayoutTransition对布局更改进行动画化。
LayoutTransition的动画效果都是设置给ViewGroup,然后当被设置动画的ViewGroup中添加删除View时体现出来。该类用于当前布局容器中有View添加、删除、隐藏、显示等时候定义布局容器自身的动画和View的动画.

LayoutTransition有下面几种转换类型动画:

  • APPEARING:当View出现或者添加的时候View出现的动画
  • CHANGE_APPEARING:当添加View导致布局容器改变的时候整个布局容器的动画。
  • DISAPPEARING:当View消失或者隐藏的时候View消失的动画
  • CHANGE_DISAPPEARING:当删除或者隐藏View导致布局容器改变的时候整个布局容器的动画
  • CHANGING:不是由于View出现或消失造成对其他View位置造成改变的时候整个布局容器的动画

使用的时候只要将ViewGroup的android:animateLayoutchanges属性设置为true,即可使用默认的动画:

<LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/verticalContainer"
    android:animateLayoutChanges="true" />

如果要使用自己的自定义动画,可以通过调用LayoutTransition的setAnimator()设置自定义的动画。

具体可参考Android属性动画Property Animation系列三之LayoutTransition(布局容器动画)

6、PropertyValuesHolder与Keyframe

PropertyValuesHolder可以生成操作几个属性的动画,可实现组合动画。

Keyframe关键帧,可以设置对应时间的的值,配合PropertyValuesHolder使用。

详细介绍可参考PropertyValuesHolder与Keyframe

7、StateListAnimator

通过StateListAnimator各种动画的搭配,我们能为不同状态下的控件提供各种动画效果。

StateListAnimator在API21才引入的,所以在5.0以上的系统才有效果。

在res/animator中新建selector文件:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true">
        <set>
            <objectAnimator android:propertyName="scaleX"
                            android:duration="@android:integer/config_shortAnimTime"
                            android:valueTo="1.5"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                            android:duration="@android:integer/config_shortAnimTime"
                            android:valueTo="1.5"
                            android:valueType="floatType"/>
        set>
    item>
    <item android:state_pressed="false">
        <set>
            <objectAnimator android:propertyName="scaleX"
                            android:duration="@android:integer/config_shortAnimTime"
                            android:valueTo="1"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                            android:duration="@android:integer/config_shortAnimTime"
                            android:valueTo="1"
                            android:valueType="floatType"/>
        set>
    item>

selector>

可以在xml文件中设置:

android:stateListAnimator=”@animator/selector_animate_scale”

也可以通过代码设置:

StateListAnimator animator = AnimatorInflater.loadStateListAnimator(this, R.animator.selector_animate_scale);
 btnStateListAnim.setStateListAnimator(animator);
8、ViewPropertyAnimator

ViewPropertyAnimator提供一种简单的方法来动画View并行地使用单个基础Animator对象。它的行为很像一个ObjectAnimator,因为它修改视图属性的实际值,但在同时动画多个属性时效率更高。

它的用法如下:

btnViewProperty.animate().x(500).y(500).start();

ViewPropertyAnimator还有好多便捷的方法:

alpha(float value),rotation(float value),scaleX(float value),translationX(float value)等等。
详情见ViewPropertyAnimator API文档

9、插值器和估值器的使用

参考Android动画系列之插值器(Interpolator)和估值器(TypeEvaluator)详解

Github示例代码

你可能感兴趣的:(Android动画系列之属性动画(Property Animation)详解)