欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android动画系列之补间动画详解

程序员文章站 2022-03-25 14:55:31
...

Android动画系列之补间动画详解

1、简介

补间动画就是对View对象的内容执行一系列简单的转换(位置、大小、旋转和透明度)。

View Animation

根据不同的效果,补间动画共分为四类:

  • 平移动画(Translate)

  • 缩放动画(scale)

  • 旋转动画(rotate)

  • 透明度动画(alpha)

分类 原理 对应Animation子类
平移动画(Translate) 移动视图的位置 TranslateAnimation
缩放动画(scale) 放大/缩小视图的大小 ScaleAnimation
旋转动画(rotate) 旋转视图的角度 RotateAnimation
透明度动画(alpha) 改变视图的透明度 AlphaAnimation

2、动画属性以及方法详解

2.1、Animation

Animation是AlphaAnimation, AnimationSet, RotateAnimation, ScaleAnimation, TranslateAnimation这些类的父类。

xml属性 作用
android:detachWallpaper 动画是否在壁纸上运行
android:duration 动画运行的时间(以毫秒为单位)
android:fillAfter 动画结束时是否保持动画最后的状态
android:fillBefore 动画结束时是否还原到开始动画前的状态
android:fillEnabled 与android:fillBefore效果相同
android:interpolator 设定插值器
android:repeatCount 动画重复次数
android:repeatMode reverse表示倒序回放,restart表示从头播放
android:startOffset 动画运行前的延迟(毫秒)
android:zAdjustment 被设置动画的内容运行时在Z轴上的位置(top/bottom/normal)
常量 作用
ABSOLUTE 指定的维度是像素的绝对数目
INFINITE 无限重复动画
RELATIVE_TO_PARENT 指定的维度持有浮点数,并应乘以被动画对象的父级的高度或宽度。
RELATIVE_TO_SELF 指定的维度持有浮点数,并应乘以动画对象自身的高度或宽度
RESTART 从头播放
REVERSE 倒序回放
START_ON_FIRST_FRAME 可以用作开始时间,以指示开始时间应该是当前时间getTransformation(long, Transformation)对于第一个动画帧调用。
ZORDER_BOTTOM
ZORDER_NORMAL 将被动画的内容按当前Z顺序保存
ZORDER_TOP 在动画期间强制将动画内容置于所有其他内容之上
2.2、AlphaAnimation

AlphaAnimation(float fromAlpha, float toAlpha)

android:fromAlpha:动画开始的透明度

android:toAlpha:动画结束的透明度

2.3、RotateAnimation

RotateAnimation(float fromDegrees, float toDegrees)

RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)

RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)

  • fromDegrees:旋转开始角度,正代表顺时针度数,负代表逆时针度数
  • toDegrees:旋转结束角度,正代表顺时针度数,负代表逆时针度数
  • pivotXType:选择起点x坐标数值的类型,Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT.默认ABSOLUTE,详见上面Animation常量解释
  • pivotXValue:起点x坐标数值
  • pivotYType:选择起点y坐标数值的类型,Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT.
  • pivotYValue:起点y坐标数值
属性:
  • android:fromDegrees:旋转开始角度,正代表顺时针度数,负代表逆时针度数

  • android:toDegrees:旋转结束角度,正代表顺时针度数,负代表逆时针度数

  • android:pivotX:旋转轴点的x坐标

  • android:pivotY:旋转轴点的y坐标

  • pivotX pivotY,可取值为数字,百分比,或者百分比p

设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。

设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF。

设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT

2.4、ScaleAnimation

ScaleAnimation(float fromX, float toX, float fromY, float toY)

ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)

ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)

  • fromX:初始X轴缩放比例,0.0-1.0,0.0表示收缩到没有;1.0表示正常无伸缩
  • toX:动画在X轴的结束缩放倍数
  • fromY:初始y轴缩放比例
  • toY:动画在y轴的结束缩放倍数
  • pivotXType:缩放轴点的x坐标的类型,Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT.默认ABSOLUTE,详见上面Animation常量解释
  • pivotXValue:缩放轴点的x坐标
  • pivotYType:与pivotXType类似
  • pivotYValue:缩放轴点的y坐标
属性:
  • android:fromXScale:初始X轴缩放比例,0.0-1.0,0.0表示收缩到没有;1.0表示正常无伸缩
  • android:toXScale:动画在X轴的结束缩放倍数
  • android:fromYScale:初始y轴缩放比例
  • android:toYScale:动画在y轴的结束缩放倍数
  • android:pivotX:缩放轴点的x坐标
  • android:pivotY:缩放轴点的y坐标
  • pivotX,pivotY可取值为数字,百分比,或者百分比p

设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。

设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF。

设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT

2.5、TranslateAnimation

TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)

TranslateAnimation(int fromXType, float fromXDelta, int toXType, float toXDelta, int fromYType, float fromYDelta, int toYType, float toYDelta)

  • fromXType,toXType,fromYType,toYType:One of Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT.
  • fromXDelta:起始点X轴坐标,对应属性android:fromXDelta
  • toXDelta:结束点X轴坐标,对应属性android:toXDelta
  • fromYDelta:起始点Y轴从标,对应属性android:fromYDelta
  • toYDelta:结束点Y轴坐标,对应属性android:toYDelta
2.6、AnimationSet

AnimationSet表示应该一起播放的一组动画。每个独立动画的转换被组合成一个单一的转换。如果动画集设置了它的子集合也设置的任何属性(例如,持续时间或之前的填充),则动画集的值将覆盖子值。

  • duration, repeatMode, fillBefore, fillAfter: These properties, when set on an AnimationSet object, will be pushed down to all child animations.(当设置在一个动画集对象,将向下推到所有的子动画)

  • repeatCount, fillEnabled: These properties are ignored for AnimationSet.(这些属性被忽略)

  • startOffset, shareInterpolator: These properties apply to the AnimationSet itself.(这些属性适用于动画集本身)

3、具体使用

3.1、在代码中使用

在代码中使用的步骤基本是类似的:

1.创建一个AnimationSet对象(Animation子类);

2.增加需要创建相应的Animation对象;

3.增加项目的需求,为Animation对象设置相应的数据;

4.将Animatin对象添加到AnimationSet对象当中;

5.使用控件对象开始执行AnimationSet。

AnimationSet animationSet = new AnimationSet(true);
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT,0f,

                        Animation.RELATIVE_TO_PARENT,0.5f,

                        Animation.RELATIVE_TO_PARENT,0f,

                        Animation.RELATIVE_TO_PARENT,0.5f
                );
translateAnimation.setDuration(2000);
animationSet.addAnimation(translateAnimation);
animationSet.setFillAfter(true);
ivAnim.startAnimation(animationSet);
注意:setFillAfter,setFillBefore要在AnimationSet中设置才有效
3.2、在xml中使用

1.在res/anim的文件夹里创建动画效果.xml文件

<translate xmlns:android="http://schemas.android.com/apk/res/android"
           android:duration="3000"
           android:repeatCount="0"
           android:repeatMode="restart"
           android:startOffset="1000"
           android:zAdjustment="bottom"

           android:fromXDelta="0"
           android:toXDelta="50%p"
           android:fromYDelta="0"
           android:toYDelta="30%p"
    >

</translate>
注意:fillafter和fillbefore这两个属性是不能够在alpha,scale,translate,rotate标签中设置的,需要在set标签中设置
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:fillBefore="false">

    <alpha
        android:fromAlpha="1"
        android:toAlpha="0"
        android:duration="3000"/>

</set>

2.代码创建Animation对象,开始动画

Animation animation = AnimationUtils.loadAnimation(this,R.anim.translate_demo1);
ivAnim.startAnimation(animation);
3.3、AnimationSet动画集的使用

xml方式:

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

    <scale
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromXScale="1.0"
        android:toXScale="1.4"
        android:fromYScale="1.0"
        android:toYScale="0.6"
        android:pivotX="50%"
        android:pivotY="50%"
        android:fillAfter="false"
        android:duration="700" />
    <set android:interpolator="@android:anim/decelerate_interpolator">
        <scale
            android:fromXScale="1.4"
            android:toXScale="0.0"
            android:fromYScale="0.6"
            android:toYScale="0.0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:startOffset="700"
            android:duration="400"
            android:fillBefore="false" />
        <rotate
            android:fromDegrees="0"
            android:toDegrees="-45"
            android:toYScale="0.0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:startOffset="700"
            android:duration="400" />
    </set>

</set>

代码实现方式:

AnimationSet setAnimation = new AnimationSet(true);
        // 步骤1:创建组合动画对象(设置为true)


        // 步骤2:设置组合动画的属性
        setAnimation.setRepeatMode(Animation.RESTART);
        setAnimation.setRepeatCount(1);

        // 步骤3:逐个创建子动画

        // 子动画1:旋转动画
        Animation rotate = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        rotate.setDuration(1000);
        rotate.setRepeatMode(Animation.RESTART);
        rotate.setRepeatCount(Animation.INFINITE);

        // 子动画2:平移动画
        Animation translate = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
                TranslateAnimation.RELATIVE_TO_PARENT,0.5f,
                TranslateAnimation.RELATIVE_TO_SELF,0
                ,TranslateAnimation.RELATIVE_TO_SELF,0);
        translate.setDuration(10000);

        // 子动画3:透明度动画
        Animation alpha = new AlphaAnimation(1,0);
        alpha.setDuration(3000);
        alpha.setStartOffset(7000);

        // 子动画4:缩放动画
        Animation scale = new ScaleAnimation(1,0.5f,1,0.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        scale.setDuration(1000);
        scale.setStartOffset(4000);

        // 步骤4:将创建的子动画添加到组合动画里
        setAnimation.addAnimation(alpha);
        setAnimation.addAnimation(rotate);
        setAnimation.addAnimation(translate);
        setAnimation.addAnimation(scale);
        ivAnim.startAnimation(setAnimation);

4、监听动画

Animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {

            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });

5、插值器的使用

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

Github示例代码