Android动画——逐帧动画

蔚落 2021-09-22 05:06 831阅读 0赞

1、概述

Android 平台有一套完整的动画框架,在Android3.0之前有两种动画,一种方式是补间动画 Tween Animation、另一种叫逐帧动画 Frame Animation(也称Drawable Animation )。这两种被归类为View Animation。 Android3.0以后增加了属性动画 Property Animation,这样子动画就分成两部分:

Center

2.使用

现在就从Drawable Animation开始说起吧。如上所述,Drawable Animation就是逐帧动画,如果大家看过老式的电影就很容易理解他的原理了,他就像电影胶带一样,按一定频率逐帧播放,使用它之前必须先定义好各个帧。在Android中逐帧动画需要得到AnimationDrawable类的支持,它位于”android.graphics.drawable.AnimationDrawable”包下,是Drawable的间接子类。它主要用来创建一个逐帧动画,并且可以对帧进行拉伸。在Android中提供了两种方式定义AnimationDrawable:XML定义资源文件和Java代码创建,采用XML的方式格式如下:

<?xml version=”1.0” encoding=”utf-8”?>

  1. <item android:drawable="@drawable/pic\_name1" android:duration="integer" />
  2. <item android:drawable="@drawable/pic\_name2" android:duration="integer" />
  3. <item android:drawable="@drawable/pic\_name3" android:duration="integer" />
  4. <item android:drawable="@drawable/pic\_name4" android:duration="integer" />

其中android:oneshot属性控制该动画播放次数,等于true时则不会循环播放,否则循环播放。标签定义各个帧显示的图片,显示顺序依照定义顺序。 然后把AnimationDrawable对象设置为View的背景即可。Android下所有的资源文件均要放在/res目录下,对于动画帧的资源需要当成一个Drawable,所以需要把它放在/res/Drawable目录下。

使用Java代码创建帧动画的方式:通过创建AnimationDrawable对象,然后调用addFrame(Drawable frame,int duration)方法想动画中添加帧,它可以设置添加动画帧的Drawable和持续时间,每调用一次,就会向元素中添加一个子元素。

下面写一个例子,模仿我们常见的加载界面,界面布局中只有一个居中的ImageView就不列出了。相对重要的是,我们需要定义一个xml文件描述各个帧,如下:

<?xml version=”1.0” encoding=”utf-8”?>

item android:drawable="@drawable/l" android:duration="500"/ item android:drawable="@drawable/o" android:duration="500"/ item android:drawable="@drawable/a" android:duration="500"/ item android:drawable="@drawable/d" android:duration="500"/ item android:drawable="@drawable/i" android:duration="500"/ item android:drawable="@drawable/n" android:duration="500"/ item android:drawable="@drawable/g" android:duration="500"/

只有AnimationDrawable对象还不能完成播放动画的功能,还需要AnimationDrawable其他的一些方法来操作逐帧动画,下面简单介绍一下AnimationDrawable的常用方法:

void start():开始播放逐帧动画。

void stop():停止播放逐帧动画。

void addFrame(Drawable frame,int duration):为AnimationDrawable添加一帧,并设置持续时间。

int getDuration(int i):得到指定index的帧的持续时间。

Drawable getFrame(int index):得到指定index的帧Drawable。

int getNumberOfFrames():得到当前AnimationDrawable的所有帧数量。

boolean isOneShot():当前AnimationDrawable是否执行一次,返回true执行一次,false循环播放。

boolean isRunning():当前AnimationDrawable是否正在播放。

void setOneShot(boolean oneShot):设置AnimationDrawable是否执行一次,true执行一次,false循环播放

Activity类如下:

public class DrawableAnimationActivity extends Activity {

private ImageView mImageViewLoading;

private ImageView mImageViewJava;

private AnimationDrawable loadingAnimation;

private AnimationDrawable javaAnimation;

private Button mButton;

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_drawable_animation);

mImageViewLoading = (ImageView) findViewById(R.id.iv_drawable_loading);

mImageViewJava = (ImageView) findViewById(R.id.iv_drawable_java);

mButton = (Button) findViewById(R.id.btn_drawable_java);

loadingAnimation = (AnimationDrawable) mImageViewLoading

.getBackground();

// 采用java代码方式创建动画

mImageViewJava.setBackgroundResource(R.drawable.loading);

javaAnimation = (AnimationDrawable) mImageViewJava.getBackground();

mButton.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

javaAnimation.start();

}

});

}

/**

* 触摸屏幕,结束动画

*/

public boolean onTouchEvent(MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_DOWN) {

loadingAnimation.stop();

return true;

}

return super.onTouchEvent(event);

}

/**

* activity显示到屏幕则开启动画

*/

@Override

public void onWindowFocusChanged(boolean hasFocus) {

// TODO Auto-generated method stub

super.onWindowFocusChanged(hasFocus);

if (hasFocus)

loadingAnimation.start();

}

}

实现的功能是:activity一启动,则动画开始,触摸屏幕时动画停止,代码比较容易理解,唯一需要注意的是,不能在onCreate()方法中调用AnimationDrawable的start()方法,因为此时AnimationDrawable还未真正加载到界面中。所以,如果想启动界面就自动运行动画,可以在OnWindowFocusChanged(boolean hasFocus)中启动动画。

效果如下:

Center 1

使用Frame Animation注意以下问题:

  1. 要在代码中调用Imageview的setBackgroundResource方法,如果直接在XML布局文件中设置其src属性当触发动画时会强制退出。
  2. 在动画start()之前要先stop(),不然在第一次动画之后会停在最后一帧,这样动画就只会触发一次。
  3. 最后一点是SDK中提到的,不要在onCreate中调用start,因为AnimationDrawable还没有完全跟Window相关联,在onCreate()方法中,View并未完全显示(同理,在此方法中测量某个View的宽高,常得到0值。也同理SurfaceHolder要增加Callback方法)。如果想要界面显示时就开始动画的话,可以在onWindowFoucsChanged()中调用start()。

参考:

http://blog.csdn.net/chziroy/article/details/40424343

http://blog.csdn.net/xyz_lmn/article/details/38667899

http://mikewang.blog.51cto.com/3826268/858171

http://www.2cto.com/kf/201312/261863.html

发表评论

表情:
评论列表 (有 0 条评论,831人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Android 动画&补间动画

    在Android开发中,有的时候为了展示更好的UI效果,通常会通过给一些UI添加动画来达到这一目的,所以Android Api定义了两种动画的Api供开发者使用:逐帧动画和补间

    相关 Android 动画OOM的解决方法

    项目中都会使用到动画,有时候会使用到逐帧动画,然后当帧数较多时,就会发生OOM的问题,网上有许多文字是提供一个工具类,解决这个方法。 关于这个工具类的使用的原文地址:[ht