美文网首页
Android属性动画详解

Android属性动画详解

作者: apeku | 来源:发表于2019-05-19 09:21 被阅读0次

前言

属性动画是Android 3.0(API 11)新加入的动画框架,属性动画弥补了视图动画的很多短板,因此已经成为大多数动画场景的首选框架。

目录

目录

1. 属性动画出现的原因

在属性动画出现以前,Android主要有两种动画,帧动画(Frame Animation)和补间动画(Tween Animation),这两种动画统称为视图动画。帧动画是通过逐帧播放图片来实现动画效果,补间动画虽然提供了旋转、缩放、位移、透明度的动画效果,却有不可忽视的3大缺陷:

  • 作用对象有限,只能作用于View及其子类
  • 动画种类有限,只有旋转、缩放、位移、透明度4种动画
  • 只是改变了View的显示效果,没有真正改变View的属性。例如:对
    View作位移的补间动画后,View虽然显示改变,但是响应区域却还在原来的位置,这在很多应用场景下是不可行的。

因此,为了弥补视图动画的不足,属性动画就应运而生了。

2. 属性动画概述

2.1 原理

属性动画通过在预设的规则下不断地改变值,并将值设置给作用对象的属性,从而达到动画效果。这个规则可以由我们定制,其中有两个重要的工具,可以帮助我们定制值的变化规则,一个是插值器(Interpolator),一个是估值器(TypeEvaluator)

2.2 插值器

插值器定义了动画的变化率,能帮助我们实现非线性改变的动画。Android提供了几种插值器,如加速变化的AccelerateInterpolator,先加速后减速的AccelerateDecelerateInterpolator等等,感兴趣的朋友可以自行百度查看。如果系统提供的插值器不能满足我们的要求,我们还可以自定义插值器(通过下面的方式)

    /**
     * 自定义插值器
     * 实现TimeInterpolator接口
     *
     */
    class MyInterpolator implements TimeInterpolator{


        //实现getInterpolation方法
        //此方法的参数input可理解为动画的进度,值的区间是在[0,1],在此区间里随着时间均匀地改变
        //返回值是内插值,从广义上理解是一个时间因子,体现了动画在时间上的变化因素;从狭义上可理解为动画改变的百分比
        @Override
        public float getInterpolation(float input) {
            return 0;
        }
    }

2.3 估值器

估值器的作用是根据开始值、结束值、开始结束之间的一个比例来计算出最终的值。在属性动画上则是计算出动画对应的最终的属性值。系统默认提供了3种估值器

  • IntEvaluator整型估值器,值的类型为整型
  • FloatEvaluator浮点型估值器,值的类型为浮点型
  • ArgbEvaluator,值的类型为ARGB值,可以用来计算颜色值
    如果系统提供的估值器不能满足我们的要求,我们还可以自定义估值器
    /**
     * 自定义估值器
     * 实现TypeEvaluator接口
     */
    class MyEvaluator implements TypeEvaluator<T>{

        /**
         *
         * @param fraction 开始过渡到结束之间的一个比例
         * @param startValue 开始值
         * @param endValue 结束值
         * @return 开始过渡到结束的具体值
         */
        @Override
        public T evaluate(float fraction, T startValue, T endValue) {
            return null;
        }
    }

3. 属性动画的使用

属性动画主要通过两个类来使用,ValueAnimator和ObjectAnimator,这两个的区别主要是ValueAnimator只是计算值,赋值给对象属性需要我们手动监听值的变化来进行;ObjectAnimator则对赋值属性这一步封装进了内部,也就是自动赋值。

3.1 ValueAnimator

3.1.1 创建ValueAnimator

创建ValueAnimator可以在代码里面创建、设置,也可以在xml里面创建、设置

  • xml创建
    res目录里创建animator目录,之后创建Animator resources file,ValueAnimator在xml文件的根结点是animator,例如:
<animator xmlns:android="http://schemas.android.com/apk/res/android"

    android:valueFrom="30"
    android:valueTo="60"
    android:duration="2000"

    android:valueType="intType" //选择值的类型
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:repeatMode="reverse"
    android:repeatCount="1">
</animator>

之后直接在代码里面加载刚才的资源文件就可以了

ValueAnimator valueAnimator= (ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.textsize_animator);

  • 代码里创建
    虽然ValueAnimator提供了公共的无参的构造方法,但是官方建议我们使用其工厂方法来创建ValueAnimator
    (1)ValueAnimator.ofInt(int... values)
    使用这种方式创建ValueAnimator,值的类型是int,会默认使用整形估值器。
    (2)ValueAnimator.ofFloat(float... values)
    对应值的类型是float,会默认使用浮点型估值器
    (3)ValueAnimator.ofArgb(int... values)
    对应值的类型是代表颜色的32位的int,会默认使用ArgbEvaluator估值器
    (4)ValueAnimator.ofObject(TypeEvaluator evaluator,Object... values)
    对应值的类型是Object,这种方式需要显式传入估值器,因为对于Object类型没有系统提供的估值器,也不可能提供估值器,因为对于不同的对象其计算方式不同
3.1.2 设置ValueAnimator

ValueAnimator提供了方法设置其动画的相关的属性,具体如下

valueAnimator.setDuration(2000);//设置动画持续时间,以毫秒为单位
valueAnimator.setInterpolator(new DecelerateInterpolator());//设置插值器
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);//设置动画重复模式,RESTART表示动画正序重复,REVERSE代表倒序重复
valueAnimator.setRepeatCount(1);//设置重复次数,也就是动画播放次数=RepeatCount+1,ValueAnimator.INFINITE表示无限重复
valueAnimator.setStartDelay(1000);//设置动画延迟播放的时间
3.1.3 监听动画值

ValueAnimator提供了回调以监听动画值,我们可以在此回调中拿到属性值并手动赋值给对象属性,从而达到效果,需要注意的是,对象是View的时候,有时需要我们在赋值属性后调用View.invalidate()或者View.requestLayout()方法来刷新界面实现视觉效果

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {//动画值更新时的监听器
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {//动画更新时会回调此方法
                Float value= (Float) animation.getAnimatedValue();//拿到更新后动画值
                tvAnimator.setTextSize(value);//手动将动画值赋值给对象
            }
        });

3.2 ObjectAnimator

ObjectAnimator利用反射调用对象属性的set方法从而自动赋值给对象属性完成动画,也就是说ObjectAnimator作用的对象必须提供该属性的set方法(如果没有提供初始值,还必须提供get方法)需要注意的是,set和get方法名必须满足如下规则
set/get+属性名(属性名头字母大写)

3.2.1 创建ObjectAnimator
  • xml创建
    res/animator目录下创建animator的xml文件,根结点为objectAnimator
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"

    android:valueType="floatType"
    android:valueTo="200.0"
    android:valueFrom="100.0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:propertyName="width"  
    />

在代码里加载xml创建的ObjectAnimator并设置作用对象

ObjectAnimator objectAnimator= (ObjectAnimator) AnimatorInflater.loadAnimator(this,R.animator.test);//加载xml中的动画
objectAnimator.setTarget(tvAnimator);//设置作用对象
  • 代码里创建
    和ValueAnimator的方式差不多,这里以ofInt为例说明创建方式,其他的可以类推。
        /*
            1. 参数解释
                target:ObjectAnimator作用的对象
                propertyName:属性名
                values:过渡值(开始值、结束值)
        */

        ObjectAnimator objectAnimator=ObjectAnimator.ofInt(Object target,String propertyName,int... values);
3.2.2 设置ObjectAnimator

同ValueAnimator设置方式一样,不再赘述。

3.3 AnimatorSet(组合动画)

AnimatorSet用于把很多动画按照一定顺序组合起来播放,AnimatorSet采用了构造器模式来组合动画

 public Builder play(Animator anim) {
    if (anim != null) {             
        return new Builder(anim);   
    }                               
    return null;                    
}                                    
//play函数会生成构造器并将该动画加入到播放队列中
                        

play函数是AnimatorSet中唯一可以创建构造器的函数,此外构造器还提供了多种方法组合动画,这些方法都是以play函数传入的Animator作为基准来构建播放顺序的,例如:

        //将animator1和animator2一起播放
        animatorSet.play(animator1).with(animator2);
        //将animator1插入animator2之后播放
        animatorSet.play(animator1).after(animator2);
        //将animator1插入animator2之前播放
        animatorSet.play(animator1).before(animator2);        

AnimatorSet本身还提供了两个方法来添加动画,

public void playSequentially(Animator... items)//一个接一个地先后播放动画组,前面的动画先播放
public void playTogether(Animator... items)//同时播放动画组

这两个方法本质上也是采用了构造器的after、before和with方法来构建动画的播放顺序。

3.4 监听动画

Animator类允许对动画开始、结束、取消、重复和暂停等时刻进行监听

animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {

            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

animator.addPauseListener(new Animator.AnimatorPauseListener() {
                @Override
                public void onAnimationPause(Animator animation) {

                }

                @Override
                public void onAnimationResume(Animator animation) {

                }
            });

如果只想监听其中的几个方法,可以采用AnimatorListenerAdapter

animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {

            }
        });

animator.addPauseListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationPause(Animator animation) {
                    
                }
            });

参考和扩展

Android 属性动画:这是一篇很详细的 属性动画 总结&攻略
属性动画 ValueAnimator 运行原理全解析

相关文章

网友评论

      本文标题:Android属性动画详解

      本文链接:https://www.haomeiwen.com/subject/golemqtx.html