zoukankan      html  css  js  c++  java
  • Android--Tween补间动画

    前言

      Android除了支持逐帧动画之外,也提供了对补间动画的支持,补间动画就是指开发人员只需要指定动画的开始、动画结束的"关键帧",而动画变化的"中间帧"由系统计算并补齐。本篇博客就讲解如何在Android下使用补间动画,最后将以简单的Demo来演示。

      本篇博客的主要内容:

    1. Animation
    2. AlphaAnimation
    3. RotateAnimation
    4. ScaleAnimation
    5. TranslateAnimation
    6. AnimationSet
    7. Animation变化坐标点的参照类型
    8. Animation的Interpolator

    Animation

      在Android中使用Tween补间动画需要得到Animation的支持,它处于"android.view.animation.Animation"包下,是一个抽象类,其中抽象了一些动画必须的方法,其子类均有对其进行实现,而在Android下完成补间动画也就是在操作Animation的几个子类。

      补间动画和逐帧动画一样,可以使用XML资源文件定义,也可以使用Java代码定义。下面提供一些常用Animation中定义的属性,同样都提供了XML属性以及对应的方法,它们主要用来设定补间动画的一些效果:

    • android:duration/setDuration(long):动画单次播放时间。
    • android:fillAfter/setFillAfter(boolean):动画是否保持播放结束位置。
    • android:fillBefore/setFillBefore(boolean):动画是否保持播放开始位置。
    • android:interpolator/setInterpolator(Interpolator):指定动画播放的速度曲线,不设定默认为匀速。
    • android:repeatCount/setRepeatCount(int):动画持续次数,如2,会播放三次。
    • android:repeatMode/setRepeatMode(int):动画播放模式。
    • android:startOffset/setStartOffset(long):动画延迟播放的时长,单位是毫秒。

      Animation中内置的方法并不只有这些,还有一些其他的控制细节的方法,有需要可以查询官方文档,这里不再详细讲解。

      上面提到,Android下对于补间动画的支持,主要是使用Animation的几个子类来实现,下面分别介绍Animation下的几个子类:

    • AlphaAnimation:控制动画透明度的变化。
    • RotateAnimation:控制动画旋转的变化。
    • ScaleAnimation:控制动画成比例缩放的变化。
    • TranslateAnimation:控制动画移动的变化。
    • AnimationSet:以上几种变化的组合。

      上面几个Animation也包含了补间动画的几种变化,如果需要使用XML资源文件定义补间动画,需要把XML资源文件定义在/res/anim/目录下,在需要使用的地方通过AnimationUtils.loadAnimation(int)方法指定XML动画ID来加载一段动画。AnimationUtils是动画工具类,其中实现了一些静态的辅助动画操作的方法。

      例如:

    1     /**
    2      * 透明度变化
    3      */
    4     protected void toAlpha() {
    5         Animation anim=AnimationUtils.loadAnimation(ToXMLActivity.this, R.anim.anim_alpha);
    6         iv_anim.startAnimation(anim);
    7     }

    AlphaAnimation

      AlphaAnimation,是Animation的子类,它用来控制透明度改变的动画。创建该动画的时候要指定动画开始的透明度、结束时候的透明度和动画的持续时间。其中透明度可以使用0~1之间的float类型的数字指定,0为透明,1为不透明。

      AlphaAnimation有两个构造函数,这里讲一个最常用最直观的,下面是它的完整签名:

        AlphaAniamtion(float fromAlpha,float toAlpha)

      上面方法指定以两个float类型的参数设定了动画开始(fromAlpha)和结束(toAlpha)的透明度。

      使用Java代码定义AlphaAnimation动画:

     1     /**
     2      * 透明度变化
     3      */
     4     protected void toAlpha() {
     5         // 动画从透明变为不透明
     6         AlphaAnimation anim = new AlphaAnimation(1.0f, 0.5f);
     7         // 动画单次播放时长为2秒
     8         anim.setDuration(2000);
     9         // 动画播放次数
    10         anim.setRepeatCount(2);
    11         // 动画播放模式为REVERSE
    12         anim.setRepeatMode(Animation.REVERSE);
    13         // 设定动画播放结束后保持播放之后的效果
    14         anim.setFillAfter(true);
    15         // 开始播放,iv_anim是一个ImageView控件
    16         iv_anim.startAnimation(anim);
    17     }

      同样可以使用XML资源文件设定AlphaAnimation,它需要使用<alpha.../>标签,为其添加各项属性:

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <alpha xmlns:android="http://schemas.android.com/apk/res/android"
    3     android:duration="2000"
    4     android:fillAfter="true"
    5     android:fromAlpha="1.0"
    6     android:repeatCount="2"
    7     android:repeatMode="reverse"
    8     android:toAlpha="0.5" >
    9 </alpha>

      在使用XML资源文件的时候,使用AnimationUtils.loadAnimation()方法加载它即可。

      效果展示:

    RotateAnimation

      RotateAnimation,是Animation的子类,它用来控制动画的旋转,创建该动画时只要指定动画旋转的"轴心坐标"、开始时的旋转角度、结束时的旋转角度,并指定动画持续时间即可。

      RotateAnimation有多个构造函数,这里讲一个参数最多的,下面是它的完整签名: 

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

      RotateAnimation中,fromDegrees和toDegrees分别指定动画开始和结束的旋转角度,pivotXType和pivotYType指定旋转中心的参照类型,它们以静态常量的形式定义在Animation中,pivotXVlaue和pivotYValue指定旋转中心的位置。

      使用Java代码定义RotateAnimation:

     1     /**
     2      * 旋转变化
     3      */
     4     protected void toRotate() {
     5         // 依照图片的中心,从0°旋转到360°
     6         RotateAnimation anim = new RotateAnimation(0, 360,
     7                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
     8                 0.5f);
     9         anim.setDuration(2000);
    10         anim.setRepeatCount(2);
    11         anim.setRepeatMode(Animation.REVERSE);
    12         iv_anim.startAnimation(anim);
    13     }

      同样可以使用XML资源文件定义RotateAnimation,它需要使用<rotate.../>标签,为其添加各项属性:

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <rotate xmlns:android="http://schemas.android.com/apk/res/android"
    3     android:duration="2000"
    4     android:fromDegrees="0"
    5     android:pivotX="50%"
    6     android:pivotY="50%"
    7     android:repeatCount="2"
    8     android:toDegrees="360" >
    9 </rotate>

      在使用XML资源文件的时候,使用AnimationUtils.loadAnimation()方法加载它即可。

      效果展示:

    ScaleAnimation

      ScaleAnimation,是Animation的子类,它用来控制动画的缩放。创建该动画时要指定开始缩放的中心坐标、动画开始时的缩放比、结束时的动画缩放比,并指定动画的持续时间即可。

      ScaleAnimation有多个构造函数,这里讲一个参数最多的,下面是它的完整签名:

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

      上面ScaleAnimation构造函数中,fronX、 toX、fromY、toY,分别指定了缩放开始和结束的坐标,pivotXType和pivotYType设定了缩放的中心类型,pivotXValue和pivotYValue设定了缩放中心的坐标。

      使用Java代码定义ScaleAnimation:

     1     /**
     2      * 比例缩放变化
     3      */
     4     protected void toScale() {
     5         // 以图片的中心位置,从原图的20%开始放大到原图的2倍
     6         ScaleAnimation anim = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
     7                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
     8                 0.5f);
     9         anim.setDuration(2000);
    10         anim.setRepeatCount(2);
    11         anim.setRepeatMode(Animation.REVERSE);
    12         iv_anim.startAnimation(anim);
    13     }

      同样可以使用XML资源文件定义ScaleAnimation,它需要使用<scale.../>标签,为其添加各项属性:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <scale xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:duration="2000"
     4     android:pivotX="50%"
     5     android:pivotY="50%"
     6     android:fromXScale="0.2"
     7     android:fromYScale="0.2"
     8     android:toXScale="2.0"
     9     android:toYScale="2.0" >
    10 </scale>

      在使用XML资源文件的时候,使用AnimationUtils.loadAnimation()方法加载它即可。

      效果展示:

     

    TranslateAnimation

      TranslateAnimation,是Animation的子类,它用来控制动画的移动。创建该动画只要指定动画开始时的位置、结束时的位置,并指定动画持续的时间即可。

       TranslateAnimation有多个构造函数,这里讲一个参数最多的,下面是它的完整签名:

        TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue)

      上面TranslateAnimation构造函数中,它们指定了动画开始的点类型以及点位置和动画移动的X、Y点的类型以及值。

      使用Java代码定义TranslateAnimation:

     1     /**
     2      * 移动变化
     3      */
     4     protected void toTranslate() {
     5         // 从父窗口的(0.1,0.1)的位置移动父窗口X轴20%Y轴20%的距离
     6         TranslateAnimation anim = new TranslateAnimation(
     7                 Animation.RELATIVE_TO_PARENT, 0.1f,
     8                 Animation.RELATIVE_TO_PARENT, 0.2f,
     9                 Animation.RELATIVE_TO_PARENT, 0.1f,
    10                 Animation.RELATIVE_TO_PARENT, 0.2f);
    11         anim.setDuration(2000);
    12         anim.setRepeatCount(2);
    13         anim.setRepeatMode(Animation.REVERSE);
    14         iv_anim.startAnimation(anim);
    15     }

      在使用XML资源文件的时候,使用AnimationUtils.loadAnimation()方法加载它即可。

      同样可以使用XML资源文件定义TranslateAnimation,它需要使用<translate.../>标签,为其添加各项属性:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <translate xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:fromXDelta="10%p" 
     4     android:toXDelta="20%p"
     5     android:fromYDelta="10%p"
     6     android:toYDelta="20%p"
     7     android:duration="2000"
     8     android:repeatCount="2" 
     9     android:repeatMode="reverse">
    10 </translate>

      在使用XML资源文件的时候,使用AnimationUtils.loadAnimation()方法加载它即可。

      效果展示:

    AnimationSet

      AnimationSet,组合动画,,是Animation的子类。有些场景需要完成透明度变化、旋转、缩放、移动等多种变化,那么就可以使用AnimationSet来完成,它可以使用addAnimation(Animation)添加多个动画进行组合播放。

      AnimationSet有多个构造函数,这里讲一个最常用的,下面是它的完整签名:

        AnimationSet(boolean shareInterpolator)

      它只有一个boolean的参数,指定是否每个动画分享自己的Interpolator,关于Interpolator的内容后面讨论,如果为false,则每个AnimationSet中的每个动画,使用自己的Interpolator。

      使用Java代码定义AnimationSet:

     1     /**
     2      * 组合动画
     3      */
     4     protected void toSetAnim() {
     5         AnimationSet animSet = new AnimationSet(false);
     6         // 依照图片的中心,从0°旋转到360°
     7         RotateAnimation ra = new RotateAnimation(0, 360,
     8                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
     9                 0.5f);
    10         ra.setDuration(2000);
    11         ra.setRepeatCount(2);
    12         ra.setRepeatMode(Animation.REVERSE);
    13 
    14         // 以图片的中心位置,从原图的20%开始放大到原图的2倍
    15         ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
    16                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
    17                 0.5f);
    18         sa.setDuration(2000);
    19         sa.setRepeatCount(2);
    20         sa.setRepeatMode(Animation.REVERSE);
    21 
    22         // 动画从透明变为不透明
    23         AlphaAnimation aa = new AlphaAnimation(1.0f, 0.5f);
    24         // 动画单次播放时长为2秒
    25         aa.setDuration(2000);
    26         // 动画播放次数
    27         aa.setRepeatCount(2);
    28         // 动画播放模式为REVERSE
    29         aa.setRepeatMode(Animation.REVERSE);
    30         // 设定动画播放结束后保持播放之后的效果
    31         aa.setFillAfter(true);
    32 
    33         animSet.addAnimation(sa);
    34         animSet.addAnimation(aa);
    35         animSet.addAnimation(ra);
    36 
    37         iv_anim.startAnimation(animSet);
    38     }

      同样可以使用XML资源文件定义AnimationSet,它需要使用<set.../>标签,为其添加各项属性:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <set xmlns:android="http://schemas.android.com/apk/res/android" >
     3 
     4     <rotate
     5         android:duration="2000"
     6         android:fromDegrees="0"
     7         android:pivotX="50%"
     8         android:pivotY="50%"
     9         android:repeatCount="2"
    10         android:toDegrees="360" >
    11     </rotate>
    12 
    13     <scale
    14         android:duration="2000"
    15         android:fromXScale="0.2"
    16         android:fromYScale="0.2"
    17         android:pivotX="50%"
    18         android:pivotY="50%"
    19         android:toXScale="2.0"
    20         android:toYScale="2.0" >
    21     </scale>
    22 
    23     <alpha
    24         android:duration="2000"
    25         android:fillAfter="true"
    26         android:fromAlpha="1.0"
    27         android:repeatCount="2"
    28         android:repeatMode="reverse"
    29         android:toAlpha="0.5" >
    30     </alpha>
    31 
    32 </set>

      在使用XML资源文件的时候,使用AnimationUtils.loadAnimation()方法加载它即可。

      效果展示:

    Animation变化坐标点的参照类型

      上面看到,RotateAnimation、ScaleAnimation、TranslateAnimation都存在一对pivotXType,pivotYType参数,它们是用来指定点的参照类型,使用int类型以静态常量的形式定义在Animation中,它有如下个值:

    • ABSOLUTE:以绝对坐标为参照。
    • RELATIVE_TO_PARENT:以父容器为参照。
    • RELATIVE_TO_SELF:以当前容器为参照。

      细心的朋友有发现到,在使用XML定义动画资源的时候,没有关于pivotXType、pivotYType两个属性,其实它们结合到了设定点的坐标中中,以 pivotXValue、pivotYValue两个属性替代,其中如果需要设定为父容器为参照,需要在属性值后面加"p"即可。

     Animation的Interpolator

      补间动画定义的是动画开始、结束的关键帧,Android需要在开始帧、结束帧之间动态计算,插入大量帧,而Interpolator用于控制"插入帧"的行为。

      Interpolator根据特定算法计算出整个动画所需要动态插入帧的密度和位置,简单来说,Interpolator负责控制动画的变化速率,用来设定与基本动画(Alpha、Scale、Rotate、Translate)的动画播放速率。

      Interpolator是一个接口,它定义了的所有Interpolator都需要实现方法:float getInterpolation(float)方法,如果需要自定义动画的变化速率,只需要重写这个接口即可,Android已经为开发人员提供了一些Interpolator的实现类,这里介绍几个常用的:

    • LineraInterpolator:动画以匀速的速度变化,默认值。
    • AccelerateInterpolator:在动画开始的时候变化速度较慢,之后开始加速。
    • AccelerateDecelerateInterpolator:在动画开始、结束的地方改变速度较慢,中间的时候加速。
    • CycleInterpolator:动画循环播放特定的次数,变化速度按照正弦曲线变化。
    • DecelerateInterpolator:在动画开始的地方速度较快,然后开始减速。

      源码下载

     

  • 相关阅读:
    字符串的格式化操作
    了解格式化输出,字符串和编码
    面试题2
    面试题1
    设计算法1
    C++ STL容器的理解
    网络是怎样连接的-路由器的附加功能
    网络是怎样连接的-路由器的包转发操作(下)
    网络是怎样连接的-路由器的包转发操作(上)
    网络是怎样连接的-交换机的包转发操作
  • 原文地址:https://www.cnblogs.com/plokmju/p/android_TweenAnimation.html
Copyright © 2011-2022 走看看