欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android 动画之 ---- Drawable Animation (Frame动画,帧动画)

程序员文章站 2022-03-16 15:10:35
...

今天我们就来学习一下Android中的Frame动画,在学习这些基础的东西我们一定要参考谷歌给我们的文档,因为谷歌的文档是最权威的讲解。官网给出的的定义:

Frame动画:包含一个接一个的将要显示的图片资源,这是一个传统的动画,它创建一个不同的图像序列,有顺序 的播放,就像一卷胶卷,我们称为帧动画。

从官网给出的定义我们不难看出其实Frame 动画就是一系列的图片的按照指定的顺序播放的过程,Frame动画可以被定义在:
1) XML: 放在res/drawable/filename.xml或者res/anim/finename.xml中
2) 代码:用到AnimationDrawable对象。
1.将动画定义在XML中官网给出的定义如下:

<?xml version="1.0" encoding="utf-8"?>  
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
    android:oneshot=["true" | "false"] >  
    <item  
        android:drawable="@[package:]drawable/drawable_resource_name"  
        android:duration="integer" />  
</animation-list>

animation-list: 是必须元素,包含一个或多个item元素.
android:oneshot: boolean类型. true: 动画只播放一次,false: 循环播放动画; 默认为fasle.
item: 一帧动画,必须有一个animation-list父节点, item节点中的属性
android:drawable 此帧动画所对应的图片资源,
android:duration 此帧动画播放所需要的时间,单位为毫秒。

帧动画需注意的事项:
官网中明确指出:
在调用AnimationDrawable.start()方法时不能在Activity的onCreate()方法中调用,因为AnimationDrawable的start方法时,窗口Window对象还没有完全初始化,AnimationDrawable不能完全追加到窗口Window对象中.
官网给出的建议是在Activity的onWindowFocusChanged方法(如果对此方法不熟可以看此博客http://blog.csdn.net/dmk877/article/details/45059261)中去调用AnimationDrawable.start()方法,因为onWindowFocusChanged在Activity窗口获得或失去焦点时调用,这时窗口已经初始化完成了。
实例展示:
(1)将动画定义在XML中
在res/drawable目录下放入资源图片:
Android 动画之 ---- Drawable Animation (Frame动画,帧动画)Android 动画之 ---- Drawable Animation (Frame动画,帧动画)Android 动画之 ---- Drawable Animation (Frame动画,帧动画)Android 动画之 ---- Drawable Animation (Frame动画,帧动画)Android 动画之 ---- Drawable Animation (Frame动画,帧动画)Android 动画之 ---- Drawable Animation (Frame动画,帧动画)Android 动画之 ---- Drawable Animation (Frame动画,帧动画)Android 动画之 ---- Drawable Animation (Frame动画,帧动画)

创建res/drawable/frame_animation.xml,frame_animation.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/img_1"        
        android:duration="200"/>
    <item        
        android:drawable="@drawable/img_2"        
        android:duration="200"/>
    <item        
        android:drawable="@drawable/img_3"        
        android:duration="200"/>
    <item        
        android:drawable="@drawable/img_4"        
        android:duration="200"/>
    <item        
        android:drawable="@drawable/img_5"        
        android:duration="200"/>
    <item        
        android:drawable="@drawable/img_6"        
        android:duration="200"/>
    <item        
        android:drawable="@drawable/img_7"        
        android:duration="200"/>
    <item        
        android:drawable="@drawable/img_8"        
        android:duration="200"/>
</animation-list>

然后布局文件:

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/frame_anim"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:layout_centerHorizontal="true"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="40dp"
            android:orientation="horizontal">

            <Button
                android:id="@+id/start_anim"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:padding="10dp"
                android:text="开始动画"
                android:textSize="20sp"/>

            <Button
                android:id="@+id/stop_anim"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:padding="10dp"
                android:text="停止动画"
                android:textSize="20sp"/>

        </LinearLayout>
    </RelativeLayout>

在MainAcitivty中启动动画:

package com.dream.drawableanimationdemo;

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.ImageView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private ImageView mImg;
    private Button mBtn1;
    private Button mBtn2;
    private AnimationDrawable mAnimationDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mImg = findViewById(R.id.frame_anim);
        mBtn1 = findViewById(R.id.start_anim);
        mBtn1.setOnClickListener(this);
        mBtn2 = findViewById(R.id.stop_anim);
        mBtn2.setOnClickListener(this);
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.start_anim:
                mAnimationDrawable.start();
                break;
            case R.id.stop_anim:
                mAnimationDrawable.stop();
                break;
        }
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        //方式一
        //mImg.setImageResource(R.drawable.frame_animation);
        // mAnimationDrawable = (AnimationDrawable) mImg.getDrawable();

        //方式二
        mImg.setBackgroundResource(R.drawable.frame_animation);
        mAnimationDrawable = (AnimationDrawable) mImg.getBackground();

        //启动动画
       mAnimationDrawable.start();
    }
}

(2)完全由代码实现动画
完全通过代码和定义在frame_animation.xml中是类似的,只不过将xml中的属性或者标签通过代码的形式来定义

private void startFrameAnim(){
        mAnimationDrawable = new AnimationDrawable();
        for ( int i = 1; i <=8; i++) {
            //根据资源名称和目录获取R.java中对应的资源ID
            int id = getResources().getIdentifier("img_" + i, "drawable" , getPackageName());
            //根据资源ID获取到 Drawable对象
            Drawable drawable = getResources().getDrawable(id);
            //将此帧添加到AnimationDrawable中
            mAnimationDrawable.addFrame(drawable,200);
        }
        //设置循环播放
        mAnimationDrawable.setOneShot( false);
        //设置图片的背景为我们的动画
        mImg.setBackgroundDrawable(mAnimationDrawable);
    }

调用代码如下:

package com.dream.drawableanimationdemo;

import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private ImageView mImg;
    private Button mBtn1;
    private Button mBtn2;
    private AnimationDrawable mAnimationDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mImg = findViewById(R.id.frame_anim);
        mBtn1 = findViewById(R.id.start_anim);
        mBtn1.setOnClickListener(this);
        mBtn2 = findViewById(R.id.stop_anim);
        mBtn2.setOnClickListener(this);

        startFrameAnim();
    }

    private void startFrameAnim(){
        mAnimationDrawable = new AnimationDrawable();
        for ( int i = 1; i <=8; i++) {
            //根据资源名称和目录获取R.java中对应的资源ID
            int id = getResources().getIdentifier("img_" + i, "drawable" , getPackageName());
            //根据资源ID获取到 Drawable对象
            Drawable drawable = getResources().getDrawable(id);
            //将此帧添加到AnimationDrawable中
            mAnimationDrawable.addFrame(drawable,200);
        }
        //设置循环播放
        mAnimationDrawable.setOneShot( false);
        //设置图片的背景为我们的动画
        mImg.setBackgroundDrawable(mAnimationDrawable);
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.start_anim:
                mAnimationDrawable.start();
                break;
            case R.id.stop_anim:
                mAnimationDrawable.stop();
                break;
        }
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        //启动动画
       mAnimationDrawable.start();
    }
}