Android——补间动画详解

序言

  • 动画是Android开发中经常使用的知识,好的动画会使你的APP看起来非常吸引人
    动画的分类
  • 本文将详细向大家解释补间动画的原理和使用方法

在这里插入图片描述

1.作用对象

  • 可以作用于各种View组件如TextView,Button,ImageView等
  • 但是不可作用于View组件的属性,如:颜色、背景、长度等等

2.原理

  • 通过确定开始的视图样式 & 结束的视图样式、中间动画变化过程由系统补全来确定一个动画
  • 即补间动画的动画效果就是:平移、缩放、旋转、透明度动画

3.分类

根据不同的动画效果,补间动画分为4种动画:

  • 平移动画(Translate)
  • 缩放动画(scale)
  • 旋转动画(rotate)
  • 透明度动画(alpha)
    同时,不同类型的动画对应于不同的子类,具体如下图:
    源码如下

各子类源码如下:

  • 平移动画
    gezilei
 /**
     * Constructor to use when building a TranslateAnimation from code
     *
     * @param fromXDelta Change in X coordinate to apply at the start of the
     *        animation
     * @param toXDelta Change in X coordinate to apply at the end of the
     *        animation
     * @param fromYDelta Change in Y coordinate to apply at the start of the
     *        animation
     * @param toYDelta Change in Y coordinate to apply at the end of the
     *        animation
     */
    public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
        mFromXValue = fromXDelta;
        mToXValue = toXDelta;
        mFromYValue = fromYDelta;
        mToYValue = toYDelta;

        mFromXType = ABSOLUTE;
        mToXType = ABSOLUTE;
        mFromYType = ABSOLUTE;
        mToYType = ABSOLUTE;
    }
  • 缩放动画
 /**
     * Constructor to use when building a ScaleAnimation from code
     * 
     * @param fromX Horizontal scaling factor to apply at the start of the
     *        animation
     * @param toX Horizontal scaling factor to apply at the end of the animation
     * @param fromY Vertical scaling factor to apply at the start of the
     *        animation
     * @param toY Vertical scaling factor to apply at the end of the animation
     * @param pivotXType Specifies how pivotXValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotXValue The X coordinate of the point about which the object
     *        is being scaled, specified as an absolute number where 0 is the
     *        left edge. (This point remains fixed while the object changes
     *        size.) This value can either be an absolute number if pivotXType
     *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
     * @param pivotYType Specifies how pivotYValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotYValue The Y coordinate of the point about which the object
     *        is being scaled, specified as an absolute number where 0 is the
     *        top edge. (This point remains fixed while the object changes
     *        size.) This value can either be an absolute number if pivotYType
     *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
     */
    public ScaleAnimation(float fromX, float toX, float fromY, float toY,
            int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
        mResources = null;
        mFromX = fromX;
        mToX = toX;
        mFromY = fromY;
        mToY = toY;

        mPivotXValue = pivotXValue;
        mPivotXType = pivotXType;
        mPivotYValue = pivotYValue;
        mPivotYType = pivotYType;
        initializePivotPoint();
    }
  • 旋转动画
/**
     * Constructor to use when building a RotateAnimation from code
     * 
     * @param fromDegrees Rotation offset to apply at the start of the
     *        animation.
     * 
     * @param toDegrees Rotation offset to apply at the end of the animation.
     * 
     * @param pivotXType Specifies how pivotXValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotXValue The X coordinate of the point about which the object
     *        is being rotated, specified as an absolute number where 0 is the
     *        left edge. This value can either be an absolute number if
     *        pivotXType is ABSOLUTE, or a percentage (where 1.0 is 100%)
     *        otherwise.
     * @param pivotYType Specifies how pivotYValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotYValue The Y coordinate of the point about which the object
     *        is being rotated, specified as an absolute number where 0 is the
     *        top edge. This value can either be an absolute number if
     *        pivotYType is ABSOLUTE, or a percentage (where 1.0 is 100%)
     *        otherwise.
     */
    public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
            int pivotYType, float pivotYValue) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;

        mPivotXValue = pivotXValue;
        mPivotXType = pivotXType;
        mPivotYValue = pivotYValue;
        mPivotYType = pivotYType;
        initializePivotPoint();
    }
  • 透明度动画
 /**
     * Constructor to use when building an AlphaAnimation from code
     * 
     * @param fromAlpha Starting alpha value for the animation, where 1.0 means
     *        fully opaque and 0.0 means fully transparent.
     * @param toAlpha Ending alpha value for the animation.
     */
    public AlphaAnimation(float fromAlpha, float toAlpha) {
        mFromAlpha = fromAlpha;
        mToAlpha = toAlpha;
    }
    

4.具体使用

  • 首先这里还有一个android坐标位置的概念:

在这里插入图片描述

坐标都是左上角为原点,然后进行坐标变化

  • 补间动画的使用方式分为两种:在XML 代码 / Java 代码里设置(若使用XML代码:在 res/anim的文件夹里创建动画效果.xml文件

前者优点:动画描述的可读性更好
后者优点:动画效果可动态创建

  • 其次要记住这4种动画的公共属性
// 以下参数是4种动画效果的公共属性,即都有的属性
    android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
    android:startOffset ="1000" // 动画延迟开始时间(ms)
    android:fillBefore =true// 动画播放完后,视图是否会停留在动画开始的状态,默认为true
    android:fillAfter =false// 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
    android:fillEnabled=true// 是否应用fillBefore值,对fillAfter值无影响,默认为true
    android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
    android:repeatCount =0// 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
    android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度   

4.1 平移动画(Translate)
设置方法1:在XML代码设置

  • 创建translate.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--平移动画的x,y起始位置-->
    <translate
        android:fromXDelta="0"
        android:toXDelta="500"
        android:fromYDelta="0"
        android:toYDelta="500"
        />
</set>

以下参数是平移动画特有的属性:

  1. android:fromXDelta="" // 视图在水平方向x 移动的起始值
  2. android:toXDelta="" // 视图在水平方向x 移动的结束值
  3. android:fromYDelta="" // 视图在竖直方向y 移动的起始值
  4. android:toYDelta="" // 视图在竖直方向y 移动的结束值
  • 在Java代码中创建Animation对象并播放动画
 		Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate);
        animation.setDuration(5000);//若xml文件为设置该属性,则不会有动画
        button.startAnimation(animation);

设置方法2:在 Java 代码中设置

		/**
         * 使用JAVA代码控制动画
         * **/
        Animation animation = new TranslateAnimation(0, screen_x, 0, screen_y);
        animation.setDuration(3000);//动画持续时间
        animation.setFillEnabled(true);//使其可以填充效果从而不回到原地
        animation.setFillAfter(true);//不回到起始位置
        //如果不添加setFillEnabled和setFillAfter则动画执行结束后会自动回到远点
        button.startAnimation(animation);

获取屏幕宽高,可以更好的控制距离
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int screen_x = metric.widthPixels; // 屏幕宽度(像素)
int screen_y = metric.heightPixels; // 屏幕高度(像素)

4.2 缩放动画(Scale)
设置方法1:在XML代码设置

  • 创建scale.xmls
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="2"
        android:toYScale="2" />
</set>

以下参数是缩放动画特有的属性

  1. android:fromXScale:动画开始时X轴方向控件大小,取值和android:pivot一样;三种取值类型:数字;百分比;百分比+”p”;

  2. android:fromYScale:动画开始时Y轴方向控件大小,取值类型同上
    动画在水平方向X的起始缩放倍数
    0.0表示起始大小收缩到没有
    1.0表示起始大小正常无伸缩
    值小于1.0表示起始大小收缩倍数
    值大于1.0表示起始大小放大倍数

  3. android:toXScale:动画在X轴方向上控件的目标大小,取值类型同上

  4. android:toYScale:动画在Y轴方向上控件的目标大小,取值类型同上

  5. android:pivotX:缩放中心坐标的X值,取值类型有三种:数字;百分比;百分比+”p”;
    数字:例如50.0,这里的单位是px像素**
    百分比:例如50%,这里是相对于自己控件宽度的百分比,实际的值是mIvImg.getWidth()50%;
    百分比+”p”:例如50%p,这里是表示相对于自己控件的父控件的百分比,

  6. android:pivotY:同上

下面详细讲解一下各属性的取值问题:

  1. 缩放的中心点位置(缩放的开始位置也就是轴点):android:pivotX/android:pivotY 取值类型有三种:数字;百分比;百分比+”p”;
  • 数字:例如50.0,这里的单位是px像素
  • 百分比:例如50%,这里是相对于自己空间宽度的百分比,实际的值是mIvImg.getWidth()*50%或者mIvImg.getHeight()*50%;
  • 百分比+”p”:例如50%p,这里是表示相对于自己控件的父控件的百分比,
    按比例缩放示意图
    按比例缩放示意图

设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。。
设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。
设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。这个很重要一个问题:它的父控件是那个,就是包裹这个空间的外一层控件,LinearLayout、RelativeLayout或者FrameLayout……

  1. 缩放的大小比例:android:fromXScale/android:fromYScale/android:toXScale/android:toYScale 取值类型有三种:数字;百分比;百分比+”p”;也就是放大倍数
  • 在Java代码中创建Animation对象并播放动画
 		 Animation animation1 = AnimationUtils.loadAnimation(this, R.anim.scale);
        animation1.setDuration(3000);
        animation1.setFillAfter(true);
        animation1.setFillEnabled(true);
        imageView.startAnimation(animation1);

设置方法2:在 Java 代码中设置

		 /**
         * 使用JAVA代码控制动画
         * **/
        Animation animation1 = new ScaleAnimation(0, 2, 0, 2, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        // 参数说明:
        // 1. fromX :动画在水平方向X的起始缩放倍数
        // 2. toX :动画在水平方向X的结束缩放倍数
        // 3. fromY :动画开始前在竖直方向Y的起始缩放倍数
        // 4. toY:动画在竖直方向Y的结束缩放倍数
        // 5. pivotXType:缩放轴点的x坐标的模式
        // 6. pivotXValue:缩放轴点x坐标的相对值
        // 7. pivotYType:缩放轴点的y坐标的模式
        // 8. pivotYValue:缩放轴点y坐标的相对值

        // pivotXType = Animation.ABSOLUTE:缩放轴点的x坐标 =  View左上角的原点 在x方向 加上 pivotXValue数值的点(y方向同理)
        // pivotXType = Animation.RELATIVE_TO_SELF:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 自身宽度乘上pivotXValue数值的值(y方向同理)
        // pivotXType = Animation.RELATIVE_TO_PARENT:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 父控件宽度乘上pivotXValue数值的值 (y方向同理)

        animation1.setDuration(3000);
        animation1.setRepeatCount(-1);//播放次数,-1循环播放
        imageView.startAnimation(animation1);

4.3 旋转动画(Rotate)
设置方法1:在XML代码设置

  • 创建rotate.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:fromDegrees="0"
        android:toDegrees="270"
        android:pivotX="50%"
        android:pivotY="50%"
        />
</set>

以下参数是平移动画特有的属性:

  1. android:pivotX:缩放中心坐标的X值
  2. android:pivotY:同上
  3. android:fromDegrees :// 动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
  4. android:toDegrees:// 动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
  • 在Java代码中创建Animation对象并播放动画
 		Animation animation2=AnimationUtils.loadAnimation(this,R.anim.rotate);
        animation2.setDuration(3000);
        button1.startAnimation(animation2);

设置方法2:在 Java 代码中设置

		 Animation animation2 = new RotateAnimation(0, 270, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        // 参数说明:
        // 1. fromDegrees :动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
        // 2. toDegrees :动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
        // 3. pivotXType:旋转轴点的x坐标的模式
        // 4. pivotXValue:旋转轴点x坐标的相对值
        // 5. pivotYType:旋转轴点的y坐标的模式
        // 6. pivotYValue:旋转轴点y坐标的相对值

        // pivotXType = Animation.ABSOLUTE:旋转轴点的x坐标 =  View左上角的原点 在x方向 加上 pivotXValue数值的点(y方向同理)
        // pivotXType = Animation.RELATIVE_TO_SELF:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 自身宽度乘上pivotXValue数值的值(y方向同理)
        // pivotXType = Animation.RELATIVE_TO_PARENT:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 父控件宽度乘上pivotXValue数值的值 (y方向同理)

        animation2.setDuration(3000);
        button1.startAnimation(animation2);

4.4 透明度动画(Alpha)
设置方法1:在XML代码设置

  • 创建alpha.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.0"
        />
</set>

以下参数是平移动画特有的属性:

  1. android:fromAlpha: // 动画开始时视图的透明度(取值范围: -1 ~ 1)
  2. android:toAlpha:// 动画结束时视图的透明度(取值范围: -1 ~ 1)
  • 在Java代码中创建Animation对象并播放动画
 		 Animation animation3=AnimationUtils.loadAnimation(this,R.anim.alpha);
        animation3.setDuration(3000);
        button2.startAnimation(animation3);

设置方法2:在 Java 代码中设置

		/**
         * 使用JAVA代码控制动画
         * **/
        Animation animation3 = new AlphaAnimation(1, 0);
        // 参数说明:
        // 1. fromAlpha:动画开始时视图的透明度(取值范围: -1 ~ 1)
        // 2. toAlpha:动画结束时视图的透明度(取值范围: -1 ~ 1)
        animation3.setDuration(3000);
        button2.startAnimation(animation3);

4.5 组合动画

  • 上面讲的都是单个动画效果;而实际中很多需求都需要同时使用平移、缩放、旋转 & 透明度4种动画,即组合动画
  • 使用组合动画需要用到标签 < Set/>

Set 对于 Animation,就类似 View 对于 ViewGroup
设置方法1:在XML代码设置

  • 创建combination.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <rotate
        android:duration="2000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="infinite"
        android:toDegrees="360" />
    <translate
        android:duration="7000"
        android:fromXDelta="0"
        android:repeatCount="infinite"
        android:toXDelta="100%p" />
    <alpha
        android:duration="7000"
        android:fromAlpha="1"
        android:repeatCount="infinite"
        android:toAlpha="0" />
    <scale
        android:duration="1000"
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="infinite"
        android:startOffset="3500"
        android:toXScale="2"
        android:toYScale="2" />
</set>
  • 在Java代码中创建Animation对象并播放动画
 		 Animation animation3=AnimationUtils.loadAnimation(this,R.anim.alpha);
        animation3.setDuration(3000);
        button2.startAnimation(animation3);

设置方法2:在 Java 代码中设置
与以上的方法类似

5.监听动画

  • Animation类通过监听动画开始 / 结束 / 重复时刻来进行一系列操作,如跳转页面等等 通过在 Java
  • 代码里setAnimationListener()方法设置
Animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                // 动画开始时回调
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                // 动画结束时回调
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                //动画重复执行的时候回调
            }
        });

特别注意

若采取上述方法监听动画,每次监听都必须重写4个方法。

背景:有些时候我们并不需要监听动画的所有时刻
问题:但上述方式是必须需要重写4个时刻的方法,这显示太累赘
解决方案:采用动画适配器AnimatorListenerAdapter,解决
实现接口繁琐 的问题
具体如下:

anim.addListener(new AnimatorListenerAdapter() {  
// 向addListener()方法中传入适配器对象AnimatorListenerAdapter()
// 由于AnimatorListenerAdapter中已经实现好每个接口
// 所以这里不实现全部方法也不会报错
    @Override  
    public void onAnimationStart(Animator animation) {  
    // 如想只想监听动画开始时刻,就只需要单独重写该方法就可以
    }  
});  

以上就是安卓补间动画的基本操作,后续知识点将继续更新。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值