【第22期】观点:IT 行业加班,到底有没有价值?

逐帧动画详解

原创 2016年08月30日 20:36:45
概述
逐帧动画(Frame Animation),是通过将一系列图片按照一定的顺序展示实现的动画。同是视图动画(View Animation),在使用时比补间动画(Tween animation)要简单很多。

一、逐帧动画的使用
(1).使用xml文件创建
节点介绍:
<animation-list>:必须作为根元素,可以包含一个或多个<item>元素。
<item>:代表一帧动画。
属性介绍:
android:oneshot:若等于true,动画只执行一次;否则一直循环。
android:drawable:当前帧所对应的图片资源。
android:duration:当前帧持续的时长,单位毫秒。

示例代码:
/res/drawable目录下添加如下5张图片。

在/res/drawable目录下添加wifi_anim.xml文件。
<?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/card_icon_wifi_0" android:duration="500" />
    <item android:drawable="@drawable/card_icon_wifi_1" android:duration="500" />
    <item android:drawable="@drawable/card_icon_wifi_2" android:duration="500" />
    <item android:drawable="@drawable/card_icon_wifi_3" android:duration="500" />
    <item android:drawable="@drawable/card_icon_wifi_4" android:duration="500" />
</animation-list>
将上面创建的动画应用到布局的View中。
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/wifi_anim"/>
在java代码中启动动画。
// 获取AnimationDrawable对象
AnimationDrawable animation = (AnimationDrawable) imageView.getBackground();
// 启动动画
animation.start();

(2).使用java代码创建
示例代码:
AnimationDrawable animation = new AnimationDrawable();
for (int i = 0; i < 5; i++) {
  int id = getResources().getIdentifier("card_icon_wifi_" + i, "drawable", getPackageName());
  Drawable drawable = getResources().getDrawable(id);
  // 调用addFrame()方法依次添加drawable对象
  animation.addFrame(drawable, 500);
}
// 添加到View中
imageView.setBackgroundDrawable(anim);
// 启动动画
animation.start();

注意:在Activity的onCreate()方法中,由于Window对象还未初始化完成,此时调用animation.start(),动画不会执行。若需要在Activity启动时就显示动画,可以在onWindowFocusChanged(boolean hasFocus)方法中启动。

二、逐帧动画的分析
逐帧动画是通过AnimationDrawable类来实现。在AnimationDrawable类中,定义了一个AnimationState类型的成员变量mAnimationState,用来存储一系列的drawable对象。
public class AnimationDrawable extends DrawableContainer implements Runnable, Animatable {
    // ...
    private AnimationState mAnimationState;
    // ...
}

AnimationState继承自DrawableContainerState类。AnimationState类自己定义了成员变量mDurations和mOneShot,分别存储每一帧的时长和动画是否需要循环。而在其父类中有一个Drawable类型数组mDrawables,用于存储每一帧drawable对象。
private final static class AnimationState extends DrawableContainerState {
    // ...
    private int[] mDurations;
    private boolean mOneShot = false;
    // ...

    public void addFrame(Drawable dr, int dur) {
        // ...
        int pos = super.addChild(dr);
        mDurations[pos] = dur;
	// ...
    }
    // ...
}

public abstract static class DrawableContainerState extends ConstantState {
    // ...
    Drawable[] mDrawables;
    // ...

    public final int addChild(Drawable dr) {
        // ...
        mDrawables[pos] = dr;
	// ...
    }
}

当调用addFrame()方法时,动画的每一帧被依次添加到成员变量mAnimationState中。
public void addFrame(@NonNull Drawable frame, int duration) {
    mAnimationState.addFrame(frame, duration);
    if (!mRunning) {
        setFrame(0, true, false);
    }
}

最后,调用start()方法启动动画。方法内部调用了setFrame()方法,在setFrame()中调用selectDrawable(),传入当前帧的索引,并在方法最后调用invalidateSelf()重写绘制。
public void start() {
    mAnimating = true;

    if (!isRunning()) {
        // Start from 0th frame.
        setFrame(0, false, mAnimationState.getChildCount() > 1
                || !mAnimationState.mOneShot);
    }
}

private void setFrame(int frame, boolean unschedule, boolean animate) {
    if (frame >= mAnimationState.getChildCount()) {
        return;
    }
    mAnimating = animate;
    mCurFrame = frame;
    selectDrawable(frame);
    if (unschedule || animate) {
        unscheduleSelf(this);
    }
    if (animate) {
        // Unscheduling may have clobbered these values; restore them
        mCurFrame = frame;
        mRunning = true;
        scheduleSelf(this, SystemClock.uptimeMillis() + mAnimationState.mDurations[frame]);
    }
}

版权声明:本文为博主原创文章,转载请注明出处。 举报

相关文章推荐

Android 逐帧动画:关于 逐帧动画 的使用都在这里了!

前言 动画的使用 是 Android 开发中常用的知识 可是动画的种类繁多、使用复杂,每当需要 采用自定义动画 实现 复杂的动画效果时,很多开发者就显得束手无策 本文将详细介绍 Android 动画中...

创建android逐帧动画的两种方式

1.设置背景方式 a.在res创建一个anim文件夹,该文件夹下创建animation_list.xml文件 <span style="font-family: Helvetica,Tahoma,Arial,sans-serif; font-size: 14px; line-...

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

android之逐帧,补间动画详解。

在android的世界中有三种动画,它们就是逐帧动画,补间动画,属性 动画。接下来我就分别演示下三种动画的简单用法。各动画的定义: 逐帧动画:就是短时间切换图片,让人们肉眼看起来是连续的,其实就是播放...

安卓逐帧动画创建(Frame Aniamtion)

                         ...

Java逐帧动画播放器V0.1.0

使用Java swing+多线程制作的播放逐帧动画的小软件。 1、一个线程加载图像。 2、一个线程定时刷新Panel播放图像。 3、一个线程请求1线程的图像。 目前CPU和内存占用比较高(CP...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)