Android Frame Animation 帧动画

Android 中的动画分为三大类 逐帧动画(Frame)补间动画(Tween)属性动画 (Property)

帧动画

帧动画 就是简单的由 N 张静态图片收集起来,然后通过控制依次显示这些图片,因为人眼"视觉残留"的原因,会让我们造成动画的"错觉",跟放电影的原理一样

而Android中实现帧动画,一般我们会用到一个 Drawable AnimationDrawable

先编写好 Drawable,然后代码中调用 start() 以及 stop() 开始或停止播放动画

当然我们也可以在Java代码中创建逐帧动画,创建 AnimationDrawable 对象,然后调用 addFrame(Drawable frame,int duration) 向动画中添加帧,接着调用 start()stop()

简单范例


  1. 创建一个 空的 Android 项目 cn.twle.android.FrameAnim

  2. 下载 /static/i/android/tuzi.zip 并把所有的图片拖到 res/drawable 目录下

  3. red/drawable 目录下创建动画 Drawable anim_tuzi.xml

    android:oneshot 是设置动画是否只是播放一次,true 只播放一次,false 循环播放

    <?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/tuzi_1"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_2"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_3"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_4"
            android:duration="80" />
       <item
            android:drawable="@drawable/tuzi_5"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_6"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_7"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_8"
            android:duration="80" />
       <item
            android:drawable="@drawable/tuzi_9"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_10"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_11"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_12"
            android:duration="80" />
    </animation-list>
    
  4. 修改布局文件 activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <Button
            android:id="@+id/btn_start"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="开始" />
    
        <Button
            android:id="@+id/btn_stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="停止" />
    
        <TextView
            android:id="@+id/img_show"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center"
            android:background="@drawable/anim_tuzi" />
    
    </LinearLayout>
    
  5. 修改 MainActivity.java 控制动画的开始以及暂停

    package cn.twle.android.frameanim;
    
    import android.graphics.drawable.AnimationDrawable;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private Button btn_start;
        private Button btn_stop;
        private TextView img_show;
        private AnimationDrawable anim;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            bindViews();
            anim = (AnimationDrawable) img_show.getBackground();
        }
    
        private void bindViews() {
            btn_start = (Button) findViewById(R.id.btn_start);
            btn_stop = (Button) findViewById(R.id.btn_stop);
            img_show = (TextView) findViewById(R.id.img_show);
            btn_start.setOnClickListener(this);
            btn_stop.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_start:
                    anim.start();
                    break;
                case R.id.btn_stop:
                    anim.stop();
                    break;
            }
        }
    }
    

在指定地方播放帧动画


  1. 创建一个 空的 Android 项目 cn.twle.android.TouchAnim

  2. 下载 /static/i/android/tuzi.zip 并把所有的图片拖到 res/drawable 目录下

  3. red/drawable 目录下创建动画 Drawable anim_tuzi.xml

    android:oneshot 是设置动画是否只是播放一次,true 只播放一次,false 循环播放

    <?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/tuzi_1"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_2"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_3"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_4"
            android:duration="80" />
       <item
            android:drawable="@drawable/tuzi_5"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_6"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_7"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_8"
            android:duration="80" />
       <item
            android:drawable="@drawable/tuzi_9"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_10"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_11"
            android:duration="80" />
        <item
            android:drawable="@drawable/tuzi_12"
            android:duration="80" />
    </animation-list>
    
  4. 自定义 ImageView: FrameView.java

    通过反射获得当前播放的帧,然后是否为最后一帧,如果是则隐藏控件

    package cn.twle.android.touchanim;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.drawable.AnimationDrawable;
    import android.util.AttributeSet;
    import android.view.View;
    import android.widget.ImageView;
    
    import java.lang.reflect.Field;
    
    public class FrameView extends ImageView {
    
        private AnimationDrawable anim;
    
        public FrameView(Context context) {
            super(context);
        }
    
        public FrameView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public FrameView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        public void setAnim(AnimationDrawable anim){
            this.anim = anim;
        }
    
        public void setLocation(int top,int left){
            this.setFrame(left,top,left + 200,top + 200);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            try{
                //反射调用AnimationDrawable里的mCurFrame值
                Field field = AnimationDrawable.class
                        .getDeclaredField("mCurFrame");
                field.setAccessible(true);
    
                // 获取 anim 动画的当前帧
                int curFrame = field.getInt(anim);
    
                // 如果已经到了最后一帧
                if (curFrame == anim.getNumberOfFrames() - 1) {
                    //让该View隐藏
                    setVisibility(View.INVISIBLE);
                }
            }catch (Exception e){e.printStackTrace();}
            super.onDraw(canvas);
        }
    }
    
  5. 修改 MainActivity.java

    创建一个 FrameLayout,添加 View,对触摸事件中按下的事件做处理,显示控件以及开启动画

    package cn.twle.android.touchanim;
    
    import android.graphics.drawable.AnimationDrawable;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.FrameLayout;
    
    public class MainActivity extends AppCompatActivity {
    
        private FrameView fView;
        private AnimationDrawable anim = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            FrameLayout fly = new FrameLayout(this);
            setContentView(fly);
    
            fView = new FrameView(this);
            fView.setBackgroundResource(R.drawable.anim_tuzi);
            fView.setVisibility(View.INVISIBLE);
            anim = (AnimationDrawable) fView.getBackground();
            fView.setAnim(anim);
            fly.addView(fView);
            fly.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    //设置按下时才产生动画效果
                    if(event.getAction() == MotionEvent.ACTION_DOWN){
                        anim.stop();
                        float x = event.getX();
                        float y = event.getY();
                        fView.setLocation((int) y - 40,(int)x-20);  //View显示的位置
                        fView.setVisibility(View.VISIBLE);
                        anim.start();    //开启动画
                    }
                    return false;
                }
            });
        }
    }
    

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.