动画总结之 逐帧动画

在 Android 中,动画分为三大类:

  • 逐帧动画:就像 gif 图片一样,整个动画是由 N 张静态图片组成,然后依次显示这些图片,就像在播放动画一样。
  • 补间动画:只需指定动画的开始和结束,中间的部分则由系统计算并补齐。
  • 属性动画:Android 3.0 后引入,通过对目标进行赋值来修改属性,并且应用对象不再是 UI 控件,而可以是任何对象。

逐帧动画

逐帧动画的原理很简单,利用了人们的“视觉停留”原理,依次播放图片,使得像是在播放动画一样,原理和电影一样。

因为逐帧动画的资源是一张张图片,所以需要将他们都放在 Drawable 目录下,在 <animation_list> 中使用 <item> 来添加一帧。

定义逐帧动画的语法格式如下:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" 
    android:oneshot=["true"|"false"] >
   <item android:drawable="@[package:]drawable/drawable_resource_name"
        android:duration="integer" /> 
</animation-list>

其中 android:oneshot 表示是否循环,值为 false 表示循环;android:duration 表示每一帧的持续时间,单位为毫秒。

在创建好动画文件之后,我们就可以将其设置为 ImageView 的背景并播放动画。

示例:
drawable_animation

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item
        android:drawable="@drawable/pic1"
        android:duration="500"></item>
    <item
        android:drawable="@drawable/pic2"
        android:duration="500"></item>
    <item
        android:drawable="@drawable/pic3"
        android:duration="500"></item>
    <item
        android:drawable="@drawable/pic4"
        android:duration="500"></item>
    <item
        android:drawable="@drawable/pic5"
        android:duration="500"></item>
</animation-list>

MainActivity

public class MainActivity extends Activity {

    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = findViewById(R.id.gif);
        AnimationDrawable animation = (AnimationDrawable) getResources().getDrawable(R.drawable.drawable_animation);

        imageView.setBackground(animation);
        animation.start();
    }
}

可以看到使用逐帧动画的步骤:

  1. 在 drawable 目录中创建动画文件
  2. 在代码中获取 AnimationDrawable 对象
  3. 将动画文件设置为 ImageView 的背景
  4. 调用 AnimationDrawable 对象的 start 方法启动动画。

在 Java 代码中定义逐帧动画

我们可以直接在代码中创建 AnimationDrawable 对象,然后调用其 addFrame 方法向 AnimationDrawable 对象中添加帧,该方法接收两个参数,第一个为每帧的资源,第二个为每帧的持续时间。每调用一次 addFrame 就相当于向 <animation-list> 当中添加一个 <item>

Android 还提供了其他方法供我们操作动画:

  • void start()
    开始播放逐帧动画。

  • void stop()
    停止播放逐帧动画。

  • void addFrame(Drawable frame,int duration)
    为AnimationDrawable添加一帧,并设置持续时间。

  • int getDuration(int i)
    得到指定index的帧的持续时间。

  • Drawable getFrame(int index)
    得到指定index的帧Drawable。

  • int getNumberOfFrames()
    得到当前AnimationDrawable的所有帧数量。

  • boolean isOneShot()
    当前AnimationDrawable是否执行一次,返回true执行一次,false循环播放。

  • boolean isRunning()
    当前AnimationDrawable是否正在播放。

void setOneShot(boolean oneShot)
设置AnimationDrawable是否执行一次,true执行一次,false循环播放

例如:

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 

        ImageView iv = (ImageView) findViewById(R.id.image); 

        AnimationDrawable ad = new AnimationDrawable(); 
        ad.addFrame(getResources().getDrawable(R.drawable.a), 500); 
        ad.addFrame(getResources().getDrawable(R.drawable.b), 500); 
        ad.addFrame(getResources().getDrawable(R.drawable.c), 500); 
        ad.addFrame(getResources().getDrawable(R.drawable.d), 500); 
        ad.addFrame(getResources().getDrawable(R.drawable.e), 500); 

        ad.setOneShot(false); 

        iv.setBackground(ad); 
        ad.start(); 
    } 
} 
Copyright© 2020-2022 li-xyz 冀ICP备2022001112号-1