Android补间动画、帧动画和属性动画使用知识介绍

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhangqunshuai/article/details/81098062

 
关于Android中动画体现,来张经典图。至于属性动画为什么要标记为红星,旨在强调,属性动画很强大,希望大家重点关注。网上资料很多。文章中会给大家推送各种链接。仅供参考。
这里写图片描述
Android动画总共包含3种动画------补间动画逐帧动画属性动画。其中补间动画和逐帧动画归属与视图动画。
 

基本概述:

补间动画(Tween Animation)

1、补间动画特性:
a.渐变动画支持四种类型:平移(Translate)、旋转(Rotate)、缩放(Scale)、不透明度
b. 只是显示的位置变动,View的实际位置未改变,表现为View移动到其他地方,点击事件仍在原处才能响应。
c. 组合使用步骤较复杂。
d. View Animation 也是指此动画。
2、补间动画的优缺点:
缺点:当平移动画执行完停在最后的位置,结果焦点还在原来的位置(控件的属性没有真的被改变)
优点:相对于逐帧动画来说,补间动画更为连贯自然

 

帧动画(Frame Animation)

1、帧动画的特性:
a. 用于生成连续的Gif效果图。
b. DrawableAnimation也是指此动画
2、帧动画的优缺点:
缺点:效果单一,逐帧播放需要很多图片,占用控件较大
优点:制作简单

 

属性动画(Property Animation)

下面我们着重介绍下属性动画,干货来了

1、属性动画的特性:
a.支持对所有View能更新的属性的动画(需要属性的setXxx()和getXxx())。
b. 更改的是View实际的属性,所以不会影响其在动画执行后所在位置的正常使用。
c. Android3.0(API11)及以后出现的功能,3.0之前的版本可使用github第三方开源库nineoldandroids.jar进行支持。

2、属性动画的优缺点:

  缺点:(3.0+API出现)向下兼容问题
  优点:易定制,效果强

 

实现步骤:

补间动画(Tween Animation)

国际惯例,上图:
这里写图片描述

Step 1: 在res资源目录下新建anim文件夹。
这里写图片描述

Step 2: 编写补间动画的xml文件,以实现透明度,旋转,缩放,平移效果。
透明度:anim_alpha.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:fillEnabled="true">
    <!--fillAfter:控件动画结束时是否保持动画最后的状态-->
    <!--fillEnabled:控件动画结束时是否还原到开始动画前的状态(同android:fillBefore)-->

    <alpha
        android:duration="2000"
        android:fromAlpha="1"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:toAlpha="0" />

</set>

 
旋转:anim_rotate.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:fillEnabled="true">
    <!--插值器accelerate_interpolator:从缓慢到加速-->
    <rotate
        android:duration="2000"
        android:fromDegrees="0"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="720"/>

    <!--startOffset:调用start函数之后等待开始运行的时间,单位为毫秒(用于顺序执行多个动画)-->
    <rotate
        android:duration="2000"
        android:fromDegrees="360"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:startOffset="2000"
        android:toDegrees="0"/>

</set>

 
缩放:anim_scale.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:fillEnabled="true">

    <!-- android:repeatMode="reverse"-->
    <scale
        android:duration="2000"
        android:fillAfter="true"
        android:fromXScale="1"
        android:fromYScale="1"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:toXScale="2.0"
        android:toYScale="2.0" />
</set>

 
平移:anim_translate.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:fillEnabled="true">
    
    <translate
        android:duration="2000"
        android:fillAfter="true"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:toXDelta="860"
        android:toYDelta="0"></translate>
</set>

对于其中的部分属性说明,可参照Android 三种动画详解,此处不再赘述。
 
Step 3: 加载补间动画

    private void initAnimal() {
        rotate = AnimationUtils.loadAnimation(this,
                R.anim.anim_rotate);
        translate = AnimationUtils.loadAnimation(this,
                R.anim.anim_translate);
        scale = AnimationUtils.loadAnimation(this,
                R.anim.anim_scale);
        alpha = AnimationUtils.loadAnimation(this,
                R.anim.anim_alpha);
    }
 switch (v.getId()) {
            //补间动画
            case R.id.btn_alpha_setting:
                ivTweenShow.startAnimation(alpha);
                break;
            case R.id.btn_rotate_setting:
                ivTweenShow.startAnimation(rotate);
                break;
            case R.id.btn_scale_setting:
                ivTweenShow.startAnimation(scale);
                break;
            case R.id.btn_translate_setting:
                ivTweenShow.startAnimation(translate);
                break;

 

帧动画(Frame Animation)

国际惯例,上图:
这里写图片描述
Step 1: 定义帧动画的资源文件
anim_frame.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/f1" android:duration="200" />
    <item android:drawable="@drawable/f2" android:duration="200" />
    <item android:drawable="@drawable/f3" android:duration="200" />
    <item android:drawable="@drawable/f4" android:duration="200" />
    <item android:drawable="@drawable/f5" android:duration="200" />
    <item android:drawable="@drawable/f6" android:duration="200" />
    <item android:drawable="@drawable/f7" android:duration="200" />
    <item android:drawable="@drawable/f8" android:duration="200" />

    <item android:drawable="@drawable/f7" android:duration="200" />
    <item android:drawable="@drawable/f6" android:duration="200" />
    <item android:drawable="@drawable/f5" android:duration="200" />
    <item android:drawable="@drawable/f4" android:duration="200" />
    <item android:drawable="@drawable/f4" android:duration="200" />
    <item android:drawable="@drawable/f3" android:duration="200" />
    <item android:drawable="@drawable/f2" android:duration="200" />
    <item android:drawable="@drawable/f1" android:duration="200" />
</animation-list>

注意,Android Studio中anim_frame.xml如果放置在res/anim文件夹下的话,会报错。因此要把它放置在res/drawable下。
 
Step 2: 引用以及加载帧动画
如果想直接显示在界面上直接在layout.xml的布局文件中使用

    <ImageView
        android:id="@+id/iv_frame_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" 
        android:background="@drawable/anim_frame"/>

当然也可以在java代码中使用

 /**
     * 开启帧动画方式1
     */
    private void startFrame() {
        stopFrame();
        if (anim == null) {
            ivFrameShow.setBackgroundResource(R.drawable.anim_frame);
            anim = (AnimationDrawable) ivFrameShow.getBackground();
        }
        anim.start();
    }

    /**
     * 开启帧动画方式2
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    private void startFrame1() {
        stopFrame();
        if (anim == null) {
            anim = (AnimationDrawable) getResources().getDrawable(
                    R.drawable.anim_frame);
            ivFrameShow.setBackground(anim);
        }
        anim.start();
    }


    /**
     * 停止帧动画
     */
    private void stopFrame() {
        if (anim != null && anim.isRunning()) { //如果正在运行,就停止
            anim.stop();
        }
    }

代码中对应帧动画启用的两种方式,已经验证,都是可以的。

 

属性动画(Property Animation)

属性动画很强大,很重要。
属性动画很强大,很重要。
属性动画很强大,很重要。
重要的事情说3遍,关于属性动画的介绍,请参照郭神的博客

Android属性动画完全解析(上),初识属性动画的基本用法
Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法
Android属性动画完全解析(下),Interpolator和ViewPropertyAnimator的用法
上面讲的很详细,此处不再重复造轮子。

下面说一下关于上述三种动画适用场景。
补间动画: 适用于对单一静态图片做旋转,平移以及缩放和透明度设置等等操作。
帧动画: 适用于构造一个类似gif动图场景,须由多张不同形态的照片来实现。有一点需要注意的是,帧动画在停止之后不能继续从停止帧继续向后执行,而是从头执行。(即没有所谓的暂停)。这也是帧动画的缺点。 因为有些场景我们需要将动画停止,然后继续从停止处执行。详情参考博文:
Android自定义View——从零开始实现可暂停的旋转动画效果,
 
这个时候我们可以通过补间动画和属性动画来实现。
属性动画: 很强大!补间动画能实现的效果属性动画都能实现,而且能更快更好更简单的实现。怎么说呢?Android3.0之前提供的补间动画机制还算相对比较健全的,比如你的需求中只需要对View进行移动、缩放、旋转和淡入淡出的操作,那么补间动画已经足够健全了。但是,如果一旦需求超出了这四种操作,补间动画就无能为力了。例如,我们需要改变View的宽度,这个时候就不能通过补间动画实现。此外,补间动画还有一个最大的缺陷,就是它只是改变了View的显示效果而已,并不会真正的改变View的属性。具体来说,例如屏幕左上角有一个Button,使用补间动画将其移动到右下角,此刻你去点击右下角的Button,它是绝对不会响应点击事件的,因此其作用区域依然还在左上角。只不过是补间动画将其绘制在右下角而已。
其中补间动画和属性动画涉及到插值器(有的称之为补间器)的使用,即,我们可以通过补间器来是设置动画变化过程,比如变化速率等等。属性动画中自定义补间器可以实现各种比较炫酷的动画。
 
 
Ok,至此完结。Android 动画是Android知识体系中的重点,希望大家能掌握。鉴于网上各种关于动画的讲解十分完善,因此有些直接添加链接,供大家查看。如有问题,请留言。我们共同探讨。

展开阅读全文

没有更多推荐了,返回首页