美文网首页
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