Android 动画应用完全解析(一)

概述

随着移动互联网的快速发展,各种移动应用也层出不穷,在追求产品功能强大的同时,对界面的显示效果也越来越苛刻。动画已经成为了各种APP的重要组成部分,成为交互中不可分割的一部分。由于平时记录的知识点比较零碎,这次对它进行统一的整理,温故知新。

动画分类

Android 系统中提供了三种方式来实现动画效果,分别是帧动画(Frame/Drawable Animation ),补间动画(Tween/View Animation),属性动画(
Property Animation)。其中帧动画和补间动画是API 11 之前推出来的,属性动画是API 11之后推出的。它们中所含的知识点如下图所示(图来自网友),后面将分别介绍它们的用法。
这里写图片描述

帧动画(Frame Animation)

Frame animation 在SDK中,称为Drawable Animation。它就像GIF图片一样,通过一系列Drawable图片资源依次显示来模拟动画的效果。
Java中对应的类为:AnimationDrawable

实现步骤:
1.在目录res/drawable 中建立资源文件。(以前是在res/anim 中,使用Android Studio中要放在drawable目录下,否则报错)

如下:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@drawable/blank01"  android:duration="200" />
    <item android:drawable="@drawable/blank02"  android:duration="200" />
    <item android:drawable="@drawable/blank03"  android:duration="200" />
    <item android:drawable="@drawable/blank04"  android:duration="200" />
    <item android:drawable="@drawable/blank05"  android:duration="200" />
    <item android:drawable="@drawable/blank06"  android:duration="200" />
</animation-list>

注意:
1。 必须作为根元素;
2。android:oneshot true:只执行一次动画,false:循环执行;
3。 作为 子元素,引用一张静态图片,代表一帧独立的动画;
4。android:duration 输入整数,表示该帧显示的时长,单位为毫秒。

2.在View控件上设置动画效果。可以直接在XML中设置android:background,或者通过代码的方式设置setBackgroundResource。

3.代码调用,AnimationDrawable类控制动画播放

        imageView = (ImageView) findViewById(R.id.imageView);
        imageView.setBackgroundResource(R.drawable.run);
        animationDrawable = (AnimationDrawable) imageView.getBackground();

        animationDrawable.start(); //播放
        animationDrawable.stop(); //停止

补间动画(Tween Animation)

Tween 动画是通过对View进行一系列的图形变化操作来实现的效果,包括:缩放,平移,旋转,渐变。因为该操作是针对View控件上的操作,所以也称为View Animation。
这里写图片描述
下面将逐一介绍上述几种动画效果

1.在XML文件中定义动画
View 动画资源全部都是放在目录:res/anim 中;
建议文件命名方式为:[ alpha | rotate | scale | translate | set ]_anim.xml;

1.1 创建渐变(alpha)效果动画资源:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fillAfter="false"
    android:fromAlpha="1.0"
    android:toAlpha="0.0">
    <!--
        浮点型值:
            fromAlpha 属性为动画起始时透明度
            toAlpha   属性为动画结束时透明度
            说明:
                0.0表示完全透明
                1.0表示完全不透明
            以上值取0.0-1.0之间的float数据类型的数字
        长整型值:
            duration  属性为动画持续时间
            说明:
                时间以毫秒为单位
        布尔型值:
            fillAfter 属性当设置为true,该动画效果在动画结束后被应用
    -->
</alpha>

1.2 创建旋转(rotate)效果动画资源:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fillAfter="true"
    android:fromDegrees="0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360">
    <!--
    属性:interpolator 指定一个动画的插值器
          有三种动画插值器:
             accelerate_decelerate_interpolator    加速-减速 动画插值器
             accelerate_interpolator               加速-动画插值器
             decelerate_interpolator               减速- 动画插值器
          其他的属于特定的动画效果
    浮点数型值:
         fromDegrees 属性为动画起始时物件的角度
         toDegrees   属性为动画结束时物件旋转的角度 可以大于360度
         说明:
                  当角度为负数——表示逆时针旋转
                  当角度为正数——表示顺时针旋转
                  (负数from——to正数:顺时针旋转)
                  (负数from——to负数:逆时针旋转)
                  (正数from——to正数:顺时针旋转)
                  (正数from——to负数:逆时针旋转)
         pivotX     动画相对于View的X坐标的开始位置
         pivotY     动画相对于View的Y坐标的开始位置
         说明:        以上两个属性值 从0%-100%中取值
                      50%为物件的X或Y方向坐标上的中点位置
     长整型值:
         duration   动画持续时间
         说明:      时间以毫秒为单位
     布尔型值:
         fillAfter  属性当设置为true,该动画效果在动画结束后被应用
    -->
</rotate>

1.3 创建平移(translate)效果动画资源:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fillAfter="true"
    android:fromXDelta="-100"
    android:fromYDelta="0"
    android:toXDelta="200"
    android:toYDelta="0">
    <!--
    整型值:
        fromXDelta 属性为动画起始时 X坐标上的位置
        toXDelta   属性为动画结束时 X坐标上的位置
        fromYDelta 属性为动画起始时 Y坐标上的位置
        toYDelta   属性为动画结束时 Y坐标上的位置
        注意:
                 没有指定fromXType toXType fromYType toYType 时候,
                 默认是以自己为相对参照物
    长整型值:
        duration  属性为动画持续时间
        说明:   时间以毫秒为单位

    布尔型值:
         fillAfter  属性当设置为true,该动画效果在动画结束后被应用
    -->
</translate>

1.4 创建缩放(scale)效果动画资源:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fillAfter="false"
    android:fromXScale="1"
    android:fromYScale="1"
    android:interpolator="@android:anim/decelerate_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="0"
    android:toYScale="0">
    <!--
       属性:interpolator 指定一个动画的插入器
       有三种动画插入器:
            accelerate_decelerate_interpolator  加速-减速 动画插入器
            accelerate_interpolator        加速-动画插入器
            decelerate_interpolator        减速- 动画插入器
       浮点型值:
            fromXScale 属性为动画起始时X坐标上的伸缩尺寸
            toXScale   属性为动画结束时X坐标上的伸缩尺寸
            fromYScale 属性为动画起始时Y坐标上的伸缩尺寸
            toYScale   属性为动画结束时Y坐标上的伸缩尺寸
            说明:
                 以上四种属性值
                    0.0表示收缩到没有
                    1.0表示正常无伸缩
                    值小于1.0表示收缩
                    值大于1.0表示放大
            pivotX     动画相对于View的X坐标的开始位置
            pivotY     动画相对于View的Y坐标的开始位置
            说明:
                    以上两个属性值 从0%-100%中取值
                    50%为物件的X或Y方向坐标上的中点位置
        长整型值:
            duration  属性为动画持续时间
            说明:   时间以毫秒为单位
        布尔型值:
            fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用
    -->
</scale>

1.5 创建set动画集合资源:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fillAfter="true"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:shareInterpolator="true">
    <rotate
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="500"
        android:toYDelta="0" />
    <scale
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="0"
        android:toYScale="0" />
    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
</set>

注意:set作为根元素是一个动画集合,里面可以包括rotate,translate,scale,alpha中一个或几个作为子节点。但是使用set时,如果想要动画执行后应用在View上,android:fillAfter需作为set的属性,否则不生效。

2.在Activity中调用XML文件中定义动画
Animation scaleAnimation = AnimationUtils.loadAnimation(this,R.anim.scale_anim);
imageView.startAnimation(scaleAnimation);
说明:与帧动画不同的是,通过AnimationUtils来加载动画xml资源,生成Animation 对象,最后通过startAnimation开始动画。
以上就完成了通过xml实现补间动画的应用,下面我们将继续总结使用Java代码的方式实现动画的应用。

3.使用JavaCode定义补间动画

上面几种动画操作类型中,都有相对应的类对象
res/anim中资源根节点
Java中操作类对象
scale ScaleAnimation
translate TranslateAnimation
rotate RotateAnimation
alpha AlphaAnimation
set AnimationSet

调用方法:

ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 200.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);

RotateAnimation rotateAnimation = new RotateAnimation(0.0f, +350.0f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f);

AlphaAnimation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);

AnimationSet animationSet = new AnimationSet(true);
animationSet.setDuration(1000);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(scaleAnimation);

开始调用:
imageView.startAnimation(animationSet);

监听补间动画的执行过程,精确控制动画:

       alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                    //动画开始
            }
            @Override
            public void onAnimationEnd(Animation animation) {
                    //动画结束
            }
            @Override
            public void onAnimationRepeat(Animation animation) {
                    //动画重新运行
            }
        });

属性动画(property Animation)

我们已经知道补间动画就是针对View进行一系列的动画操作,包括淡入淡出(alpha),缩放(scale),平移(translate),旋转(rotate)。 这些操作仅仅改变了View的显示效果并没有修改View的真实属性,如位置,宽高等。而属性动画(property Animation)能够真正改变对象的属性。
这里写图片描述
上面是属性动画中的五大核心类,最常使用的是:ValueAnimator,ObjectAnimator,AnimatorSet。

ValueAnimator:对值进行了一个平滑的动画过渡;

ObjectAnimator:它是可以直接对任意对象的任意属性进行动画操作的,但是作用的对象必须提供该属性的get和set方法;

AnimatorSet:同时操作一个或以上的属性动画,按照特定顺序执行的动画集合,作用与AnimationSet 类似,但用法不同;

1.在XML文件中定义属性动画
与补间动画不同的是,属性动画资源全部都是放在目录:res/animator 中;
建议文件命名方式为:[ value | objectvalue | set ]_animator.xml;
在XML文件中我们一共可以使用如下三种标签;
对应代码中的ValueAnimator
对应代码中的ObjectAnimator
对应代码中的AnimatorSet

1.1.1 创建ValueAnimator 对应的资源文件

<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:repeatCount="3"
    android:repeatMode="restart"
    android:startOffset="2000"
    android:valueFrom="#000000"
    android:valueTo="#FF3DFF"
    android:valueType="colorType">
    <!--
    属性说明:
        duration 动画的时长,int类型,以毫秒为单位,默认为300毫秒。
        repeatCount 一个动画的重复次数,int型
            说明:
               -1 表示无限循环
               1  表示动画在第一次执行完成后重复执行一次
               0  默认值,不重复执行
        repeatMode 重复模式
             说明:
                reverse 会使得按照动画向相反的方向执行。
                repeat  会使得动画每次都从头开始循环。
        startOffset   动画延迟的时间,从调用start方法后开始计算,int型,毫秒为单位
        valueFrom   动画的起始点,Float、int或者color,也是必须值,颜色由6位十六进制的数字表示
        valueTo       动画结束的点
        valueType   关键参数,说明动画操作值的类型,valueFrom,valueTo的值类型要与之对应
             说明:
                colorType   颜色的变化
                intType       整数的变化
                floatType    小数的变化
                pathType    路径的变化,5.0L新特性,配合VectorDrawable使用
    -->
</animator>

上面xml文件中表示的是,颜色在500毫秒中的渐变。

1.1.2 在代码中调用animator资源文件

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

        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                number.setBackgroundColor((Integer) animation.getAnimatedValue());
            }
        });

        animator.start();

注意:与View animation不同的是,加载属性动画资源是通过类AnimatorInflater,生成的对象为Animator。

1.1.3 创建objectAnimator对应的资源文件

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:propertyName="translationX"
    android:repeatCount="3"
    android:repeatMode="restart"
    android:startOffset="1000"
    android:valueFrom="0.0f"
    android:valueTo="300.0f"
    android:valueType="floatType">
    <!--
    属性说明:
        objectAnimator 中有一个特殊的属性:
        propertyName
            String类型,必须要设定的值,代表要执行动画的属性。
            动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新对象的某个属性,对象必须得有getter和setter方法,
            这个objectAnimator元素没有暴露target属性,因此比不能够在XML中执行一个动画,
            必须通过调用loadAnimator() 填充你的XML动画资源,并且调用setTarget() 应用到拥有这个属性的目标对象上。
    -->
</objectAnimator>

1.1.4 在代码中调用objectAnimator资源文件

      Animator objectAnimator = AnimatorInflater.loadAnimator(this,R.animator.valueobject_animator);
        objectAnimator.setTarget(imageView);
        objectAnimator.start();

注意:在加载objectAnimator 的资源后,需要设置setTarget,这样才能关联到View,更新View的属性。

1.1.5 创建AnimatorSet对应的资源文件

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together">
    <objectAnimator
        android:duration="100"
        android:propertyName="translationX"
        android:startOffset="1000"
        android:valueFrom="0.0f"
        android:valueTo="500.0f"
        android:valueType="floatType" />
    <set android:ordering="together">
        <objectAnimator
            android:duration="3000"
            android:propertyName="rotation"
            android:valueFrom="0"
            android:valueTo="360"
            android:valueType="floatType" />
        <objectAnimator
            android:duration="1500"
            android:propertyName="alpha"
            android:valueFrom="1"
            android:valueTo="0"
            android:valueType="floatType" />
    </set>
</set>

如上,在set中可以同时执行几个不同的动画效果,属性android:ordering=”together” 用来控制动画的播放顺序。

1.1.6 在代码中调用AnimatorSet资源文件

     Animator objectAnimator = AnimatorInflater.loadAnimator(this,R.animator.set);
        objectAnimator.setTarget(imageView);
        objectAnimator.start();

总结:从上面可以看出,除了ValueAnimator 需要转型为对应的ValueAnimator 之外,其他的都可以通过Animator 的对象操作。

2.用Java代码定义属性动画
2.1 定义ValueAnimator 对象

     ValueAnimator animator = ValueAnimator.ofInt(1,100);
        animator.setDuration(1000);
        animator.setInterpolator(new DecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                number.setText(String.valueOf(animation.getAnimatedValue()));
            }
        });
        animator.start();

2.2 定义ObjectAnimator 对象

    ObjectAnimator animator = new ObjectAnimator();
        animator.setDuration(500);               //动画播放时长
        animator.setPropertyName("translationX");   //设置需要修改的属性
        animator.setTarget(imageView);          //修改属性的对象
        animator.setFloatValues(0, 5000);        //修改的属性值范围
        animator.setStartDelay(2000);           //动画延迟多长后开始
        animator.start();                       //开始动画

2.3 定义AnimatorSet对象

    ObjectAnimator translation = new ObjectAnimator();
        translation.setPropertyName("translationX");
        translation.setFloatValues(0, 500);

        ObjectAnimator rotation = new ObjectAnimator();
        rotation.setPropertyName("rotationX");
        rotation.setFloatValues(0, 360);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(translation).with(rotation);
        animatorSet.setDuration(500);
        animatorSet.setStartDelay(1000);
        animatorSet.setTarget(imageView);
        animatorSet.start();

注意:
after(Animator anim) 将现有动画插入到传入的动画之后执行
after(long delay) 将现有动画延迟指定毫秒后执行
before(Animator anim) 将现有动画插入到传入的动画之前执行
with(Animator anim) 将现有动画和传入的动画同时执行

3.添加属性动画监听器
animatorSet.addListener(new AnimatorListenerAdapter());
animatorSet.addListener(new AnimatorListener());

注意:AnimatorSet 和 AnimationSet的区别
1.AnimatorSet 是属性动画的集合,AnimationSet 用于补间动画的集合;
2.AnimationSet :调用其 addAnimation 将一个个不一样的动画组织到一起来,然后调用view 的 startAnimation 方法触发这些动画执行。功能较弱不能做到把集合中的动画按一定顺序进行组织然后在执行的定制。 是针对视图外观的动画实现,动画被应用时外观改变但视图的触发点不会发生变化,还是在原来定义的位置。

AnimatorSet :我们最常用的是调用其play、before、with、after 等方法设置动画的执行顺序,然后调用其start 触发动画执行。是针对视图属性的动画实现,动画被应用时对象属性产生变化,最终导致视图外观变化。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值