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

Android动画-全面归纳解析

程序员文章站 2022-06-28 14:30:22
...

简介

Android中,动画整体来说可以分为三大类,分别为:帧动画(Frame Animation),补间动画(Tween Animation)和属性动画(Property Animation),下面内容将会对这三种动画做详细讲解。

1)帧动画(Frame Animation)

帧动画,它是通过顺序播放一系列的图像从而产生动画的效果,类似于gif图的效果。Android中给我们提供AnimationDrawable类来使用帧动画,下面我们使用帧动画来实现如下加载页面。

Android动画-全面归纳解析
该效果实际上就是通过一系列图片按顺序播放而实现的效果。

首先,我们需要准备好这一系列图片:

Android动画-全面归纳解析

然后,在drawable文件加下创建view_loading.xml文件:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@drawable/icon_loading_1" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_2" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_3" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_4" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_5" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_6" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_7" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_8" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_9" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_10" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_11" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_12" android:duration="200"/>
    <item android:drawable="@drawable/icon_loading_13" android:duration="200"/>
  </animation-list>

android:duration 表示展示该图片的时间长度

最后,在activity中添加如下代码:

private void initView(){
        ivLoading = (ImageView) findViewById(R.id.iv_loading);

        AnimationDrawable animationDrawable = (AnimationDrawable) getResources().getDrawable(R.drawable.view_loading);
        ivLoading.setBackground(animationDrawable);
        animationDrawable.start();
}

即完成上图效果,是不是十分简单。

总结:

通过上面的代码,我们可以发现,实现帧动画非常简单,首先通过 animation-list标签将多张有序的图片顺序摆放,其次通过AnimationDrawable的start函数执行,最后一个事先约定好的动画就呈现了。

那么帧动画有什么优缺点呢?

优点:

1.代码简单,可实现由一系列图片构成的不规则动画;

缺点:

1、可能涉及到大量的图片,消耗内存,图片过多可能导致OOM;

2、只能作用在某一个View上。


2)补间动画(Tween Animation)

补间动画,它主要是对View做一些简单的动画操作,例如透明渐变、位置移动、旋转及拉伸等操作。

下面首先颜色下透明渐变的实现过程,效果图如下:

Android动画-全面归纳解析

如何实现该渐变过程?

首先,在res目录下创建anim文件夹,在anim文件夹下创建xml文件,具体如下:

Android动画-全面归纳解析

具体内容为:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
	android:duration="3000"
	android:fillAfter="true"
	android:fromAlpha="1.0"
	android:toAlpha="0.1" />

然后,在activity中添加相关代码:

private void initView(){
        imageView = (ImageView) findViewById(R.id.iv_1);

        Animation anim = AnimationUtils.loadAnimation(this, R.anim.tween_animation_alpha);
        imageView.startAnimation(anim);
    }

如上,即可完成渐变效果。

补间动画,还有其他几种效果,具体实现和渐变效果实现类似,此处不在展示,可以参考补间动画详解

总结

补间动画,主要是针对View做一些简单的操作,例如透明度、位置移动、旋转和拉伸等,同时我们可以使用set来对这几种操作集合起来做一些比较稍微炫酷的效果。

优点

相比帧动画,它少了图片的加载,可以一定程度减少ANR和OOM的产生,节省系统资源。

缺点

它仍然只能对一个View做相关的动画效果,不能改变View的属性,例如移动后的View是不能点击的,即点击事件无法与动画同时兼顾。

应用场景:Activity的切换效果、fragment的切换效果及dialog的进入退出效果等。


3)属性动画(Property Animation)

属性动画,它是在android3.0(API 11)后才提供的一种动画模式,弥补了补间动画的一些缺陷,例如按钮的点击事件。属性动画它作用的对象不再局限与View了,可以是任意一个对象,也可以自定义各种动画效果。

属性动画主要有两个重要的类,分别为ValueAnimatorObjectAnimator

  • ValueAnimator类

ValueAnimator是属性动画机制中最核心的一个类,其运行机制是通过不断地修改对象的值来实现动画。使用过程中我们只需要将初始值和结束值提供给ValueAnimator ,并且告诉它动画所需运行的时长,那么ValueAnimator 就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。除此之外ValueAnimator 还负责管理动画的播放次数、播放模式、以及对动画设置监听器等。

下面我们具体来看一个实例:

xml文件

<Button
        android:id="@+id/btn_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮一"/>

activity.java

private Button btn01;

private void initView(){
        btn01 = (Button) findViewById(R.id.btn_1);

        btn01.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                btn1Animator();
            }
        });
    }
// 启动动画
private void btn1Animator() {

        // 步骤1:设置属性数值的初始值 & 结束值
        // 初始值 = 100
        // 结束值 = 500
        // ValueAnimator.ofInt()内置了整型估值器,直接采用默认的.不需要设置
        ValueAnimator valueAnimator = ValueAnimator.ofInt(100, 500);

        // 步骤2:设置动画的播放各种属性
        // 设置动画运行时长:2s
        valueAnimator.setDuration(2000);


        // 步骤3:将属性数值手动赋值给对象的属性:此处是将 值 赋给 按钮的宽度
        // 设置更新监听器:即数值每次变化更新都会调用该方法
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animator) {

                int currentValue = (Integer) animator.getAnimatedValue();
                // 获得每次变化后的属性值
                // 输出每次变化后的属性值进行查看
                Log.i("lvjie", "currentValue="+currentValue);


                // 每次值变化时,将值手动赋值给对象的属性
                // 即将每次变化后的值 赋 给按钮的宽度,这样就实现了按钮宽度属性的动态变化
                btn01.getLayoutParams().width = currentValue;


                // 步骤4:刷新视图,即重新绘制,从而实现动画效果
                btn01.requestLayout();

            }
        });

        // 启动动画
        valueAnimator.start();
    }

运行结果如下:

Android动画-全面归纳解析

我们不仅可以通过代码来实现动画,同时我们也可以通过xml文件来实现动画。需要注意的是 属性动画的xml文件必须是在res/animator文件夹下。

下面看看 value_animation.xml文件的具体实现:

<?xml version="1.0" encoding="utf-8"?>
<animator  xmlns:android="http://schemas.android.com/apk/res/android"
    android:valueFrom="100"
    android:valueTo="500"
    android:valueType="intType"
    android:duration="3000"
    android:repeatCount = "1"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
>
</animator>

然后activity.java中代码如下:

private void btn2Animator() {
        // 载入XML动画
        ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.value_animation);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int currentValue = (Integer) animation.getAnimatedValue();
                btn02.getLayoutParams().width = currentValue;
                btn02.requestLayout();
            }
        });
        // 启动动画
        animator.start();

    }

最终效果和代码实现一模一样。

  • ObjectAnimator类

ObjectAnimator继承ValueAnimator类,因此具备ValueAnimator的所有特性,与ValueAnimator不同的是ObjectAnimator可以自动给对象的属性进行赋值从而实现动画,ValueAnimator需要在监听事件中手动对对象进行赋值,下面看看ObjectAnimator最简单用法。

实现方式一:Java代码实现

private void btn3Animator() {

        // 表示的是:
        // 动画作用对象是mButton
        // 动画作用的对象的属性是X轴缩放
        // 动画效果是:放大到2倍,再缩小到初始大小
        ObjectAnimator animator = ObjectAnimator.ofFloat(btn03, "scaleX", 1f, 2f, 1f);

        animator.setDuration(3000);
        animator.start();
    }

实现方式二:通过xml实现

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator   xmlns:android="http://schemas.android.com/apk/res/android"
    android:valueFrom="1"
    android:valueTo="2"
    android:valueType="floatType"
    android:duration="3000"
    android:propertyName="scaleX">
</objectAnimator >
private void btn4Animator() {

        // 载入XML动画
        ObjectAnimator animator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_animation);
        animator.setTarget(btn04);
        // 启动动画
        animator.start();

    }

两种实现的效果一样,xml的实现方式仅仅扩大,没有恢复效果。

总结

在使用过程中,我们使用ObjectAnimator比重相对较大,ObjectAnimator内部封装了很多其他实用的方法,便于快速开发实现动画效果。

参考文献

https://www.jianshu.com/p/733532041f46

https://mp.weixin.qq.com/s/vh8Updq6hIcwLSxQP3gSlQ


相关标签: android 动画