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

Android 动画(一)ViewAnimation

程序员文章站 2022-06-06 15:29:31
...

在 Android 动画中,总共有两种类型的动画 View Animation(视图动画)和 Property Animator(属性动画),其中View Animation 又包括 Tween Animation(补间动画)和 Frame Animation(逐帧动画):

  • 补间动画:对视图的内容执行一系列简单的转换(位置,大小,旋转等等)
  • 逐帧动画,逐个加载一系列Drawable资源。

这两种动画类型都可以在任何View对象中使用,以提供简单的旋转计时器,活动图标和其他有用的UI元素。补间动画由这个包处理(android.view.animation); 逐帧动画由AnimationDrawable类处理。
Android 动画(一)ViewAnimation
这一篇介绍(总结)View Animation中的Tween Animation(补间动画)的操作 。

我始终坚信冰山理论,我们所接触到的不过是冰山一角,更多讲解及知识请查看官网:
https://developer.android.google.cn/training/animation/overview

一 View Animation

两个动画的关键类

  • Transformation 变换类
  • Animation 动画类

动画机制:动画由动画模型及变换矩阵组成,首先需要定义动画模型或动画参数,然后传到Transformation中运算,再由View呈现。在android中 Transformation类已经被封装到了android.view.animation.Animation类中,所以我们在Animation类及其子类中只需要传递相应动画参数便可实现动画效果。
Android 动画(一)ViewAnimation

通用的动画属性:
android:detachWallpaper 窗口动画的特殊选项:如果此窗口位于壁纸顶部,请不要使用它为壁纸设置动画。
android:duration 动画运行的时间周期(以毫秒为单位)。
android:fillAfter 设置为true时,保持显示动画运行完成后的状态
android:fillBefore 设置为true或fillEnabled未设置为true时,将在动画开始之前应用动画变换(也就是在动画结束后会显示动画初始时的状态)。
android:fillEnabled 设置为true时,将考虑fillBefore的值。
android:interpolator 定义用于平滑动画移动的插值器。
android:repeatCount 定义动画应重复的次数。
android:repeatMode 定义到达结尾时的动画行为,并且重复计数大于0或无限。 Animation.RESTART 当动画到达结尾并且重复计数为INFINTE_REPEAT或正值时,动画将从头开始重新开始 Animation.REVERSE 当动画到达结尾并且重复计数为INFINTE_REPEAT或正值时,动画向后播放(然后再向前播放)。
android:startOffset 一旦达到开始时间,动画运行前的延迟时间为毫秒。
android:zAdjustment 允许在动画持续时间内调整动画内容的Z轴顺序。 Animation.ZORDER_TOP 设置永远在最顶端,不被其他控件遮挡 ZORDER_NORMAL 请求将动画内容保持为当前的Z顺序。 ZORDER_BOTTOM 请求在动画持续期间强制动画内容在所有其他内容下。


AnimationSet用于构建组合动画

在AnimationSet类中定义应该一起播放的一组动画。每个单独的动画的转换组成一个单一的转换。如果AnimationSet设置其子项也设置的任何属性(例如duration或fillBefore),则AnimationSet的值会覆盖子值。

AnimationSet从动画中继承行为的方式非常重要。应用于AnimationSet的一些Animation属性会影响AnimationSet本身,有些会被推送到子节点,有些会被忽略,如下所示:

• duration,repeatMode,fillBefore,fillAfter:这些属性在AnimationSet对象上设置时,将被推送到所有子动画。
• repeatCount,fillEnabled:AnimationSet会忽略这些属性。
• startOffset,shareInterpolator:这些属性适用于AnimationSet本身。

从Build.VERSION_CODES.ICE_CREAM_SANDWICH这些属性开始,这些属性的行为在XML资源和运行时是相同的(在该版本之前,对于AnimationSet忽略了在XML中设置的值)。也就是说,调用 setDuration(500) AnimationSet具有与android:duration=”500”在XML资源中为AnimationSet对象声明相同的效果。

构造函数:
public AnimationSet(boolean shareInterpolator) 如果此集合中的所有动画应使用与此AnimationSet关联的插补器,则传递true。如果每个动画应该使用自己的插值器,则传递false。

单一动画:

1.1 Alpha 透明动画
自身属性:
• android:fromAlpha 动画开始的透明度,从 0.0 –1.0 ,0.0 表示全透明,1.0 表示完全不透明
• android:toAlpha 动画结束时的透明度,也是从 0.0 –1.0 ,0.0 表示全透明,1.0 表示完全不透明
XML代码:

<?xml version="1.0" encoding="utf-8"?>  
<alpha xmlns:android="http://schemas.android.com/apk/res/android"  
    android:fromAlpha="1.0"  
    android:toAlpha="0.1"  
    android:duration="2000" 
    android:repeatCount="5"
    android:repeatMode="reverse"
    android:fillBefore="true">  
</alpha>  

Java代码:

   /**
     * 透明动画
     */
    private void alphaAnimation() {
        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.1f);
        alphaAnimation.setDuration(2000);//设置周期
        alphaAnimation.setRepeatCount(5);//设置运行次数
        alphaAnimation.setRepeatMode(Animation.REVERSE);//设置相反运行模式
        alphaAnimation.setFillAfter(true);//设置是否显示动画运行完成后状态
        alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                LogUtil.i(TAG, "onAnimationStart");
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                LogUtil.i(TAG, "onAnimationEnd");
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                LogUtil.i(TAG, "onAnimationRepeat");
            }
        });
        //启动动画
        ivImage.startAnimation(alphaAnimation);
    }

1.2 Rotate 旋转动画
自身属性:
android:fromDegrees 开始旋转的角度位置,正值代表顺时针方向度数,负值代码逆时针方向度数
• android:toDegrees 结束时旋转到的角度位置,正值代表顺时针方向度数,负值代码逆时针方向度数
• android:pivotX 缩放起点 X 轴坐标,可以是数值、百分数、百分数 p 三种样式,比如 50、50%、50%p,具体意义已在 scale 标签中讲述,这里就不再重讲
• android:pivotY 缩放起点 Y 轴坐标,可以是数值、百分数、百分数 p 三种样式,比如 50、50%、50%p

XML代码:

<?xml version="1.0" encoding="utf-8"?>  
<rotate xmlns:android="http://schemas.android.com/apk/res/android"  
    android:fromDegrees="0"  
    android:toDegrees="360"  
    android:pivotX="50%"  
    android:pivotY="50%"  
    android:duration="3000"  
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:fillAfter="true">  
</rotate>  

Java代码:

    /**
     * 旋转动画
     */
    private void RotateAnimation() {
        //Animation.RELATIVE_TO_SELF 相对于自己
        //Animation.RELATIVE_TO_PARENT 相对于父节点
        RotateAnimation rotateAnimation = new RotateAnimation(-30, 30, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setDuration(500);//设置周期
        rotateAnimation.setRepeatCount(Animation.INFINITE);//设置为无限次
        rotateAnimation.setRepeatMode(Animation.REVERSE);
        //启动动画
        ivImage.startAnimation(rotateAnimation);
    }

1.3 Scale

缩放动画
• 自身属性:
• android:fromXScale 起始的 X 方向上相对自身的缩放比例,浮点值,比如 1.0 代表自身无变化,0.5 代表起始时缩小一倍,2.0 代表放大一倍;
• android:toXScale 结尾的 X 方向上相对自身的缩放比例,浮点值;
• android:fromYScale 起始的 Y 方向上相对自身的缩放比例,浮点值,
• android:toYScale 结尾的 Y 方向上相对自身的缩放比例,浮点值;
• android:pivotX 缩放起点 X 轴坐标,可以是数值、百分数、百分数 p 三种样式,比如 50、50%、50%p,当为数值时,表示在当前 View 的左上角,即原点处加上 50px,做为起始缩放点;如果是 50%,表示在当前控件的左上角加上自己宽度的 50%做为起始点;如果是 50%p,那么就是表示在当前的左上角加上父控件宽度的 50%做为起始点 x 轴坐标。(具体意义,后面会举例演示)
• android:pivotY 缩放起点 Y 轴坐标,取值及意义跟 android:pivotX 一样。

XML代码:

<?xml version="1.0" encoding="utf-8"?>  
<scale xmlns:android="http://schemas.android.com/apk/res/android"  
    android:fromXScale="0.5"  
    android:toXScale="1.5"  
    android:fromYScale="0.5"  
    android:toYScale="1.5"  
    android:pivotX="50%"  
    android:pivotY="50%"  
    android:repeatCount="3"
    android:repeatMode="reverse"
    android:duration="1000" />  

Java代码:

    /**
     * 缩放动画
     */
    private void ScaleAnimation() {
        ScaleAnimation scaleAnimation = new ScaleAnimation(0.5f, 1.5f, 0.5f, 1.5f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 1.0f);
        scaleAnimation.setDuration(1000);
        scaleAnimation.setRepeatCount(3);
        scaleAnimation.setRepeatMode(Animation.REVERSE);
        scaleAnimation.setZAdjustment(Animation.ZORDER_TOP);//设置永远在最顶端,不被其他控件遮挡
        ivImage.startAnimation(scaleAnimation);
    }

1.4 Tran

slate 位移动画
• android:fromXDelta 起始点 X 轴坐标,可以是数值、百分数、百分数 p 三种样式,比如 50、50%、50%p
• android:fromYDelta 起始点 Y 轴从标,可以是数值、百分数、百分数 p 三种样式;
• android:toXDelta 结束点 X 轴坐标
• android:toYDelta 结束点 Y 轴坐标

XML代码:

<?xml version="1.0" encoding="utf-8"?>  
<translate xmlns:android="http://schemas.android.com/apk/res/android"  
    android:fromXDelta="0"   
    android:toXDelta="100%"  
    android:fromYDelta="0"  
    android:toYDelta="100%"  
    android:duration="1000"  
    android:repeatCount="3"
    android:repeatMode="reverse"
    android:fillBefore="true">  
</translate>  

Java代码:

    /**
     * 位移动画
     */
    private void translateAnimation() {
        //ABSOLUTE 绝对像素
        TranslateAnimation translateAnimation = new TranslateAnimation(
                Animation.RELATIVE_TO_SELF, 0,
                Animation.RELATIVE_TO_SELF, 1f,
                Animation.RELATIVE_TO_SELF, 0,
                Animation.RELATIVE_TO_SELF, 1f);
        translateAnimation.setDuration(1000);
        translateAnimation.setRepeatCount(3);
        translateAnimation.setRepeatMode(Animation.REVERSE);
        translateAnimation.setZAdjustment(Animation.ZORDER_TOP);//设置永远在最顶端,不被其他控件遮挡
        ivImage.startAnimation(translateAnimation);

    }

1.5 复杂动画

    /**
     * 复杂动画
     */
    private void ComplexAnimation() {
        AnimationSet set = new AnimationSet(false);

        //透明
        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.1f);
        alphaAnimation.setDuration(3000);//设置周期
        //旋转
        RotateAnimation rotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setDuration(3000);//设置周期
        //缩放
        ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 0.3f, 1.0f, 0.3f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        scaleAnimation.setDuration(3000);
        //位移
        TranslateAnimation translateAnimation = new TranslateAnimation(
                Animation.RELATIVE_TO_SELF, 0,
                Animation.RELATIVE_TO_SELF, 1f,
                Animation.RELATIVE_TO_SELF, 0,
                Animation.RELATIVE_TO_SELF, 1f);
        translateAnimation.setDuration(3000);

        set.addAnimation(alphaAnimation);
        set.addAnimation(rotateAnimation);
        set.addAnimation(scaleAnimation);
        set.addAnimation(translateAnimation);
        ivImage.startAnimation(set);
    }

加载anim文件中配置的动画
Java代码:

 private void xmlComplexAnimation(){
        AnimationSet set = (AnimationSet)AnimationUtils.loadAnimation(this,R.anim.anim_complex_test);
        ivImage.startAnimation(set);
    }

anim_complex_test.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:repeatMode="reverse"
    android:repeatCount="3"
    >
    <!--设置透明度-->
    <alpha android:fromAlpha="1.0"
           android:toAlpha="0.1"/>
    <!--设置缩放-->
    <scale android:pivotY="0.5"
           android:pivotX="0.5"
           android:fromXScale="1.0"
           android:fromYScale="1.0"
           android:toXScale="0.1"
           android:toYScale="0.1"/>
    <!--设置旋转-->
    <rotate android:fromDegrees="0"
            android:toDegrees="720"
            android:pivotX="0.5"
            android:pivotY="0.5"/>
    <!--设置位移-->
    <translate android:fromXDelta="0"
               android:fromYDelta="0"
               android:toXDelta="1"
               android:toYDelta="1"/>
</set>

动画效果:
Android 动画(一)ViewAnimation