美文网首页
Android动画详解-帧动画

Android动画详解-帧动画

作者: 有腹肌的豌豆Z | 来源:发表于2020-09-09 09:01 被阅读0次
  • 帧动画就是顺序播放一组预先定义好的图片,就类似于我们观看视频,就是一张一张的图片连续播放。
  • 帧动画的使用很简单,总共就两个步骤:
    1、在res/drawable目录下定义一个XML文件,根节点为系统提供的animation-list,然后放入定义更好的图片;
    2、使用AnimationDrawable类播放第一步定义好的Drawable中的图片,形成动画效果;
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/image01" android:duration="500"/>
    <item android:drawable="@drawable/image02" android:duration="500"/>
    <item android:drawable="@drawable/image03" android:duration="500"/>
</animation-list>

// android:oneshot=“false”: 表示是否重复播放动画,还是只播放一次;
// 每个item都有Drawable和duration属性,Drawable表示我们要播放的图片;duration表示这张图播放的时间;
java 代码创建
        imageView_2 = findViewById(R.id.image_2);
        AnimationDrawable animationDrawable1 = new AnimationDrawable();
        animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_1 ),200);
        animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_2 ),200);
        animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_3 ),200);
        animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_4 ),200);
        animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_5 ),200);
        animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_6 ),200);
        animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_7 ),200);
        animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_8 ),200);
        animationDrawable1.setOneShot(true);
        imageView_2.setImageDrawable(animationDrawable1);
        animationDrawable1.start();
运行
    Button button = (Button) findViewById(R.id.bt_001);
    button.setBackgroundResource(R.drawable.frame_animation);//把Drawable设置为button的背景
    //拿到这个我们定义的Drawable,实际也就是AnimationDrawable
    AnimationDrawable animationDrawable = (AnimationDrawable) button.getBackground();
    animationDrawable.start();//开启动画

AnimationDrawable

  • AnimationDrawable继承自Drawable。
  • AnimationDrawable会一次性把所有图片加载到内存中。
    我们是通过xml文件保存帧动画信息的,所以从Drawable.createFromXml()方法看起:
构造函数
 public AnimationDrawable() {
        this(null, null);
    }

 private AnimationDrawable(AnimationState state, Resources res) {
        final AnimationState as = new AnimationState(state, this, res);
        setConstantState(as);
        if (state != null) {
            setFrame(0, true, false);
        }
    }

AnimationState

  • 内部类
private final static class AnimationState extends DrawableContainerState {
        private int[] mDurations; // 保存图片资源的 
        private boolean mOneShot = false; // 是否显示一次 控制循环播放动画

        // 添加一帧图片
        public void addFrame(Drawable dr, int dur) {
            // Do not combine the following. The array index must be evaluated before
            // the array is accessed because super.addChild(dr) has a side effect on mDurations.
            int pos = super.addChild(dr);
            mDurations[pos] = dur;
        }

}
start() 开启动画
@Override
    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) {
       // 当前frame是否超过了现实的范围 
       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动画详解-帧动画

      本文链接:https://www.haomeiwen.com/subject/gwffektx.html