美文网首页
Android Animation梳理

Android Animation梳理

作者: 安静的蓝孩子 | 来源:发表于2019-01-09 16:40 被阅读0次

    Android 中动画分为早期的 Animation (视图动画) 和 Android 3.0 增加的 Animator (属性动画)。这里主要记录 Animation 的使用方法。

    一、Animation

    Animation

    二、FrameAnimation (逐帧动画)

    FrameAnimation 就是通过逐帧播放来实现的动画。

    逐帧动画示例

    使用步骤:

    1. res/drawable 文件夹下新建 animation-listXML;
    <?xml version="1.0" encoding="utf-8"?>
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="false">
    
        <!-- animation-list 帧动画 -->
        <!-- android:oneshot的值为 false代表播放多次,true代表只播放一次 -->
        <!-- duration代表每张图片的播放时间 ,定义一个持续时间为50毫秒的动画帧 -->
        <item
            android:drawable="@drawable/loading_1"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_2"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_3"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_4"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_5"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_6"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_7"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_8"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_9"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_10"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_11"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_12"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_13"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_14"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_15"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_16"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_17"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_18"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_19"
            android:duration="50" />
        <item
            android:drawable="@drawable/loading_20"
            android:duration="50" />
    
    </animation-list>
    
    1. 添加控件,设置 background;

    直接在 XML 中声明背景图片:

    <ImageView
            android:id="@+id/iv_loading"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/loading_anim_layout"/>
    

    也可以动态设置背景图片:

    mIvLoading = findViewById(R.id.iv_loading);
            AnimationDrawable animationDrawable = (AnimationDrawable) getResources().getDrawable(R.drawable.loading_anim_layout);
            mIvLoading.setBackground(animationDrawable);
    
    1. 开启和关闭帧动画;
      设置完背景图片后,需要调用动画启动的函数,不然默认只会停留在第一帧处。
      如:
    ((AnimationDrawable)mIvLoading.getBackground()).start();
    //stop() 停止播放
    
    1. 第一步中设置帧也可以直接在代码中添加;
    private void setFrameAnimation() {
            AnimationDrawable animationDrawable = new AnimationDrawable();
            //为AnimationDrawable添加动画帧
            animationDrawable.addFrame(getResources().getDrawable(R.drawable.loading_1), 50);
            animationDrawable.addFrame(getResources().getDrawable(R.drawable.loading_2), 50);
            animationDrawable.addFrame(getResources().getDrawable(R.drawable.loading_3), 50);
            animationDrawable.addFrame(getResources().getDrawable(R.drawable.loading_4), 50);
            //...
            // 设置为循环播放  
            animationDrawable.setOneShot(true);
            mIvLoading.setBackground(animationDrawable);
        }
    

    三、TweenAnimation 补间动画

    Tween 动画是通过对 View 进行一些列的图像变换,包括平移、缩放、旋转、透明度变化,从而达到动画效果。
    Tween 动画并不改变 View 的属性,只是改变了 View 绘制的位置,没有改变 View 对象本身。比如屏幕左上角的一个空间,通过补间动画平移到右上角后,其点击区域还是在左上角。

    实现补帧动画有两种方式,XML 中声明和直接代码两种方式。

    (1) AlphaAnimation(透明度)

    1. XML 方式实现:
      res/anim/ 目录下添加 XML 文件
    <?xml version="1.0" encoding="utf-8"?>
    <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:fillAfter="false"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
    
    • fromAlpha : 开始时透明度,0 是完全透明,1 是完全不透明;
    • toAlpha : 结束时透明度,0 是完全透明,1 是完全不透明;
    • duration : 动画持续时间,单位毫秒;
    • fillAfter :动画结束后是否停留在最后一帧。默认 false
    • fillBefore :动画结束后是否停留在第一帧。默认 true。和 fillAfter同时设置则只会看 fillAfter
    • fillEnbabled : 与 android:fillBefore 效果相同?
    • interpolator : 指定插值器

    获取动画并设置给对应的 View

    Animation alphaAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_alpha);
            mIvLoading.startAnimation(alphaAnimation);
    
    1. 代码实现方式:
    Animation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
            alphaAnimation.setDuration(500);//设置动画持续时间为500毫秒
            alphaAnimation.setFillAfter(false);//设置动画结束后保持当前的位置(即不返回到动画开始前的位置)
            mIvLoading.startAnimation(alphaAnimation);
    

    (2) ScaleAnimation(缩放)

    1. XML 实现方式:
    <?xml version="1.0" encoding="utf-8"?>
    <scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:fromXScale="0.0"
        android:fromYScale="0.0"
        android:toXScale="1.0"
        android:toYScale="1.0" />
    
    • fromXScalefromYScale : 动画开始前X,Y的缩放,0.0 为不显示,1.0 为正常大小;
    • toXScaletoYScale: 动画最终缩放的倍数, 1.0 为正常大小,大于 1.0 放大,小于 1.0 缩小;

    还可以设置:

    • pivotXpivotY : 动画起始位置,相对于自身的百分比,两个都为 50% 表示动画从自身中间开始;
    • repeatCount : 动画重复的计数,动画将会执行该值 +1 次;
    • repeatMode : 动画重复的模式,reverse 为反向,当第偶次执行时,动画方向会相反。restart 为重新执行,方向不变;
    • startOffset : 动画多次执行的间隔时间,如果只执行一次,执行前会暂停这段时间,单位毫秒;
    • fromXDelta, fromYDelta : 起始时 XY 座标;
    • toXDeltatoYDelta : 动画结束时 X, Y 的座标;

    获取动画并设置给对应的 View

    Animation scaleAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_scale);
            mIvLoading.startAnimation(scaleAnimation);
    
    1. 代码实现方式:
    Animation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            scaleAnimation.setDuration(1000);
            scaleAnimation.setRepeatCount(3);//设置动画循环次数
            scaleAnimation.setRepeatMode(Animation.REVERSE);
            scaleAnimation.setStartOffset(0);
            scaleAnimation.setInterpolator(this, android.R.anim.decelerate_interpolator);//设置动画插入器
            mIvLoading.startAnimation(scaleAnimation);
    

    (3) RotateAnimation(旋转)

    1. XML 实现方式:
    <?xml version="1.0" encoding="utf-8"?>
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />
    
    • fromDegrees : 动画开始时的角度;
    • toDegrees : 动画结束时的角度,为正顺时针旋转,为负逆时针旋转;

    获取动画并设置给对应的 View

    Animation rotateAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_rotate);
            mIvLoading.startAnimation(rotateAnimation);
    
    1. 代码实现方式:
    Animation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            rotateAnimation.setDuration(1000);
            rotateAnimation.setFillAfter(true);
            mIvLoading.startAnimation(rotateAnimation);
    

    (4) TranslateAnimation(平移)

    1. XML 实现方式:
    <?xml version="1.0" encoding="utf-8"?>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="100"
        android:toYDelta="100" />
    
    • fromXDelta, fromYDelta : 起始时 XY 座标;
    • toXDeltatoYDelta : 动画结束时 X, Y 的座标;

    获取动画并设置给对应的 View

    Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_translate);
            mIvLoading.startAnimation(translateAnimation);
    
    1. 代码实现方式:
    Animation translateAnimation = new TranslateAnimation(0, 0, 100, 100);
            translateAnimation.setDuration(1000);
            mIvLoading.startAnimation(translateAnimation);
    

    (5) AnimationSet(动画集合)

    XML 实现方式:

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillAfter="true">
    
        <!-- 各种单独特效的杂糅 -->
        <alpha
            android:duration="1000"
            android:fromAlpha="1.0"
            android:toAlpha="0.1" />
    
        <rotate
            android:duration="1000"
            android:fromDegrees="0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="720" />
    
        <scale
            android:duration="1000"
            android:fromXScale="0.1"
            android:fromYScale="0.1"
            android:toXScale="1.0"
            android:toYScale="1.0" />
    
        <translate
            android:duration="1000"
            android:fillAfter="true"
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:toXDelta="100"
            android:toYDelta="100" />
    </set>
    

    获取动画并设置给对应的 View

    Animation animationSet = AnimationUtils.loadAnimation(this, R.anim.tween_anim_set);
            mIvLoading.startAnimation(animationSet);
    

    代码方式实现:

    AnimationSet animationSet = new AnimationSet(true);
            Animation alphaAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_alpha);
            Animation scaleAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_scale);
            Animation rotateAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_rotate);
            Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_translate);
            animationSet.addAnimation(alphaAnimation);
            animationSet.addAnimation(scaleAnimation);
            animationSet.addAnimation(rotateAnimation);
            animationSet.addAnimation(translateAnimation);
    
            mIvLoading.startAnimation(animationSet);
    

    四、动画监听器

    有时,我们需要知道动画的一些状态,然后在不同的周期做相应的操作,这时可以使用动画监听器,如下:

    animationSet.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
            //动画开始时调用
        }
    
        @Override
        public void onAnimationEnd(Animation animation) {
            //动画结束时调用
        }
    
        @Override
        public void onAnimationRepeat(Animation animation) {
            //动画重复时调用
        }
        });
    

    相关文章

      网友评论

          本文标题:Android Animation梳理

          本文链接:https://www.haomeiwen.com/subject/iyegrqtx.html