Android逐帧动画

3,939 阅读2分钟

前言

逐帧动画(Frame Animation),是最简单最直观的动画类型,它利用人眼的视觉暂留效应 ---- 也就是光对视网膜所产生视觉在光停止动作后,仍然保留一段时间的现象。 开发者指定动画中每一帧对应的图片和持续时间,就可以开始播放动画。定义逐帧动画,可以采用 XML 资源文件或者代码实现。

作用对象

视图控件(View)

  • 如Android的TextView、Button等等
  • 不可作用于View组件的属性,如:颜色、背景、长度等等

原理

  • 将动画拆分为 帧 的形式,且定义每一帧 = 每一张图片
  • 逐帧动画的本质:按序播放一组预先定义好的图片

具体使用

1、XML 资源文件方式

图片资源(460x540)放置在mipmap中,命名方式以字母+数字序列组合。

新建一个动画 XML 文件,在文件中使用 标签来定义动画帧序列,使用 标签来定义动画的每一帧,并在其中指定帧的持续时间等属性。

res/drawable/animalist.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="@mipmap/p0"
        android:duration="50" />
    //此处省略p1-p58...   
    <item
        android:drawable="@mipmap/p59"
        android:duration="50" />
</animation-list>

oneshot 用来控制动画是否循环播放,如果取值为 true,表示动画不会循环播放,否则动画会循环播放;duration 用来指定每一帧的持续播放时间。

res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="horizontal"
        tools:context=".MainActivity">
        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/animalist" />
    </LinearLayout>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal|center_vertical"
        android:orientation="horizontal"
        tools:context=".MainActivity">

        <Button
            android:id="@+id/startAnimationBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="startFrameAnimation"
            android:text="start animation" />
    </LinearLayout>
</RelativeLayout>
MainActivity.java
ImageView image = (ImageView) findViewById(R.id.image);
AnimationDrawable animationDrawable = (AnimationDrawable) image.getDrawable();
    animationDrawable.stop();
    animationDrawable.selectDrawable(0);
	animationDrawable.start();

2、代码方式

AnimationDrawable animationDrawable = new AnimationDrawable();
ImageView image = (ImageView) findViewById(R.id.image);
int id = 0;
for (int i = 0; i < 60; i++) {
    id = getResources().getIdentifier("p" + i, "mipmap",getPackageName());
    Drawable drawable = getResources().getDrawable(id);
    animationDrawable.addFrame(drawable, 100);
}
image.setImageDrawable(animationDrawable);
animationDrawable.setOneShot(false);
animationDrawable.start();

优缺点

  • 优点:使用简单、方便
  • 缺点:容易引起 OOM( java.lang.OutOfMemoryError ),因为会使用大量 & 尺寸较大的图片资源

性能检测-Android Profiler

最终效果

代码

Github demo code