Android中的逐帧动画

  先来说说什么是逐帧动画,逐帧动画是一种常见的动画形式(Frame By Frame),其原理是在“连续的关键帧”中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。 因为逐帧动画的帧序列内容不一样,不但给制作增加了负担而且最终输出的文件量也很大,但它的优势也很明显:逐帧动画具有非常大的灵活性,几乎可以表现任何想表现的内容,而它类似与电影的播放模式,很适合于表演细腻的动画。

  在Android中逐帧动画需要得到AnimationDrawable类的支持,它位于"android.graphics.drawable.AnimationDrawable"包下,是Drawable的间接子类。它主要用来创建一个逐帧动画,并且可以对帧进行拉伸,把它设置为View的背景即可使用AnimationDrawable.start()方法播放。既然逐帧动画是需要播放一帧一帧的图像,所以需要为其添加帧。在Android中提供了两种方式为AnimationDrawable添加帧:XML定义的资源文件和Java代码创建,后面再详细讲讲这两种添加帧的方式。

  光为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循环播放

使用XML定义的资源文件设置动画帧

  Android下所有的资源文件均要放在/res目录下,对于动画帧的资源需要当成一个Drawable,所以需要把它放在/res/Drawable目录下。而定义逐帧动画非常简单,只要在<animation-list.../>元素中使用<item.../>子元素定义动画的全部帧,并制定各帧的持续时间即可。还可以在<animation-list.../>元素中添加属性,来设定逐帧动画的属性。

  例如:

1 <?xml version="1.0" encoding="utf-8"?>
2 <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false" >
3 <!-- 定义一个动画帧,Drawable为img0,持续时间50毫秒 -->
4 <item android:drawable="@drawable/img0" android:duration="50" />
5 </animation-list>

  定义好逐帧动画的资源文件之后,只需要使用getResources().getDrawable(int)方法获取AnimationDrawable示例,然后把它设置为某个View的背景即可。

  下面通过一个简单的Demo,来演示如何播放一个XML定义的逐帧动画,布局很简单,一个ImageView来承载逐帧动画,两个Button控制播放与停止:

  XML帧动画的资源文件:

 1 <?xml version="1.0" encoding="utf-8"?>
2 <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false" >
3 <!-- 定义一个动画帧,Drawable为img0,持续时间50毫秒 -->
4 <item android:drawable="@drawable/img0" android:duration="50" />
5 <item android:drawable="@drawable/img1" android:duration="50" />
6 <item android:drawable="@drawable/img2" android:duration="50" />
7 <item android:drawable="@drawable/img3" android:duration="50" />
8 <item android:drawable="@drawable/img4" android:duration="50" />
9 <item android:drawable="@drawable/img5" android:duration="50" />
10 <item android:drawable="@drawable/img6" android:duration="50" />
11 <item android:drawable="@drawable/img7" android:duration="50" />
12 <item android:drawable="@drawable/img8" android:duration="50" />
13 <item android:drawable="@drawable/img9" android:duration="50" />
14 <item android:drawable="@drawable/img10" android:duration="50" />
15 <item android:drawable="@drawable/img11" android:duration="50" />
16 <item android:drawable="@drawable/img12" android:duration="50" />
17 <item android:drawable="@drawable/img13" android:duration="50" />
18 <item android:drawable="@drawable/img14" android:duration="50" />
19 <item android:drawable="@drawable/img15" android:duration="50" />
20 <item android:drawable="@drawable/img16" android:duration="50" />
21 <item android:drawable="@drawable/img17" android:duration="50" />
22 <item android:drawable="@drawable/img18" android:duration="50" />
23 <item android:drawable="@drawable/img19" android:duration="50" />
24 <item android:drawable="@drawable/img20" android:duration="50" />
25 <item android:drawable="@drawable/img21" android:duration="50" />
26 <item android:drawable="@drawable/img22" android:duration="50" />
27 <item android:drawable="@drawable/img23" android:duration="50" />
28 <item android:drawable="@drawable/img24" android:duration="50" />
29 </animation-list>

  实现代码:

 1 package cn.bgxt.frameanimationdemo;
2
3 import android.app.Activity;
4 import android.graphics.drawable.AnimationDrawable;
5 import android.os.Bundle;
6 import android.util.Log;
7 import android.view.View;
8 import android.view.View.OnClickListener;
9 import android.widget.Button;
10 import android.widget.ImageView;
11 import android.widget.Toast;
12
13 public class ToXMLActivity extends Activity {
14
15 private Button btn_start, btn_stop;
16 private ImageView iv_frame;
17 private AnimationDrawable frameAnim;
18
19 @Override
20 protected void onCreate(Bundle savedInstanceState) {
21 super.onCreate(savedInstanceState);
22 setContentView(R.layout.activity_frameanim);
23
24 btn_start = (Button) findViewById(R.id.btn_start);
25 btn_stop = (Button) findViewById(R.id.btn_stop);
26
27 btn_start.setOnClickListener(click);
28 btn_stop.setOnClickListener(click);
29
30 iv_frame = (ImageView) findViewById(R.id.iv_frame);
31
32 // 通过逐帧动画的资源文件获得AnimationDrawable示例
33 frameAnim=(AnimationDrawable) getResources().getDrawable(R.drawable.bullet_anim);
34 // 把AnimationDrawable设置为ImageView的背景
35 iv_frame.setBackgroundDrawable(frameAnim);
36 }
37
38 private View.OnClickListener click = new OnClickListener() {
39
40 @Override
41 public void onClick(View v) {
42 switch (v.getId()) {
43 case R.id.btn_start:
44 start();
45 break;
46 case R.id.btn_stop:
47 stop();
48 break;
49 default:
50 break;
51 }
52 }
53 };
54
55 /**
56 * 开始播放
57 */
58 protected void start() {
59 if (frameAnim != null && !frameAnim.isRunning()) {
60 frameAnim.start();
61 Toast.makeText(ToXMLActivity.this, "开始播放", 0).show();
62 Log.i("main", "index 为5的帧持续时间为:"+frameAnim.getDuration(5)+"毫秒");
63 Log.i("main", "当前AnimationDrawable一共有"+frameAnim.getNumberOfFrames()+"帧");
64 }
65 }
66
67 /**
68 * 停止播放
69 */
70 protected void stop() {
71 if (frameAnim != null && frameAnim.isRunning()) {
72 frameAnim.stop();
73 Toast.makeText(ToXMLActivity.this, "停止播放", 0).show();
74 }
75 }
76 }

使用Java代码创建逐帧动画

  在Android中,除了可以通过XML文件定义一个逐帧动画之外,还可以通过AnimationDrawable.addFrame()方法为AnimationDrawable添加动画帧,上面已经提供了addFrame()的方法签名,它可以设置添加动画帧的Drawable和持续时间。其实没什么技术含量,下面通过一个简单的Demo演示一下。

  实现代码:

  1 package cn.bgxt.frameanimationdemo;
2
3 import android.app.Activity;
4 import android.graphics.BitmapFactory;
5 import android.graphics.Canvas;
6 import android.graphics.ColorFilter;
7 import android.graphics.drawable.AnimationDrawable;
8 import android.graphics.drawable.BitmapDrawable;
9 import android.graphics.drawable.Drawable;
10 import android.os.Bundle;
11 import android.view.View;
12 import android.view.View.OnClickListener;
13 import android.widget.Button;
14 import android.widget.ImageView;
15 import android.widget.Toast;
16
17 public class ToCodeActivity extends Activity {
18 private Button btn_start, btn_stop;
19 private ImageView iv_frame;
20 private AnimationDrawable frameAnim;
21
22 @Override
23 protected void onCreate(Bundle savedInstanceState) {
24 super.onCreate(savedInstanceState);
25 setContentView(R.layout.activity_frameanim);
26
27 btn_start = (Button) findViewById(R.id.btn_start);
28 btn_stop = (Button) findViewById(R.id.btn_stop);
29
30 btn_start.setOnClickListener(click);
31 btn_stop.setOnClickListener(click);
32
33 iv_frame = (ImageView) findViewById(R.id.iv_frame);
34
35 frameAnim =new AnimationDrawable();
36 // 为AnimationDrawable添加动画帧
37 frameAnim.addFrame(getResources().getDrawable(R.drawable.img0), 50);
38 frameAnim.addFrame(getResources().getDrawable(R.drawable.img1), 50);
39 frameAnim.addFrame(getResources().getDrawable(R.drawable.img2), 50);
40 frameAnim.addFrame(getResources().getDrawable(R.drawable.img3), 50);
41 frameAnim.addFrame(getResources().getDrawable(R.drawable.img4), 50);
42 frameAnim.addFrame(getResources().getDrawable(R.drawable.img5), 50);
43 frameAnim.addFrame(getResources().getDrawable(R.drawable.img6), 50);
44 frameAnim.addFrame(getResources().getDrawable(R.drawable.img7), 50);
45 frameAnim.addFrame(getResources().getDrawable(R.drawable.img8), 50);
46 frameAnim.addFrame(getResources().getDrawable(R.drawable.img9), 50);
47 frameAnim.addFrame(getResources().getDrawable(R.drawable.img10), 50);
48 frameAnim.addFrame(getResources().getDrawable(R.drawable.img11), 50);
49 frameAnim.addFrame(getResources().getDrawable(R.drawable.img12), 50);
50 frameAnim.addFrame(getResources().getDrawable(R.drawable.img13), 50);
51 frameAnim.addFrame(getResources().getDrawable(R.drawable.img14), 50);
52 frameAnim.addFrame(getResources().getDrawable(R.drawable.img15), 50);
53 frameAnim.addFrame(getResources().getDrawable(R.drawable.img16), 50);
54 frameAnim.addFrame(getResources().getDrawable(R.drawable.img17), 50);
55 frameAnim.addFrame(getResources().getDrawable(R.drawable.img18), 50);
56 frameAnim.addFrame(getResources().getDrawable(R.drawable.img19), 50);
57 frameAnim.addFrame(getResources().getDrawable(R.drawable.img20), 50);
58 frameAnim.addFrame(getResources().getDrawable(R.drawable.img21), 50);
59 frameAnim.addFrame(getResources().getDrawable(R.drawable.img22), 50);
60 frameAnim.addFrame(getResources().getDrawable(R.drawable.img23), 50);
61 frameAnim.addFrame(getResources().getDrawable(R.drawable.img24), 50);
62 frameAnim.setOneShot(false);
63
64 // 设置ImageView的背景为AnimationDrawable
65 iv_frame.setBackgroundDrawable(frameAnim);
66 }
67
68 private View.OnClickListener click = new OnClickListener() {
69
70 @Override
71 public void onClick(View v) {
72 switch (v.getId()) {
73 case R.id.btn_start:
74 start();
75 break;
76 case R.id.btn_stop:
77 stop();
78 break;
79 default:
80 break;
81 }
82
83 }
84 };
85
86 /**
87 * 开始播放
88 */
89 protected void start() {
90 if (frameAnim != null && !frameAnim.isRunning()) {
91 frameAnim.start();
92 Toast.makeText(ToCodeActivity.this, "开始播放", 0).show();
93 }
94 }
95 /**
96 * 停止播放
97 */
98 protected void stop() {
99 if (frameAnim != null && frameAnim.isRunning()) {
100 frameAnim.stop();
101 Toast.makeText(ToCodeActivity.this, "停止播放", 0).show();
102 }
103 }
104
105 }

  其实上面两个Demo实现的都是一种效果,是一个子弹击中墙体的逐帧动画效果,下面展示一下Demo的运行效果:

andorid frameanimation的更多相关文章

  1. Andorid实现点击获取验证码倒计时效果

    这篇文章主要介绍了Andorid实现点击获取验证码倒计时效果,这种效果大家经常遇到,想知道如何实现的,请阅读本文   我们在开发中经常用到倒计时的功能,比如发送验证码后,倒计时60s再进行验证码的获取 ...

  2. 第一章 Andorid系统移植与驱动开发概述 - 读书笔记

    Android驱动月考1 第一章 Andorid系统移植与驱动开发概述 - 读书笔记 1.Android系统的架构: (1)Linux内核,Android是基于Linux内核的操作系统,并且开源,所以 ...

  3. Cordova webapp实战开发:(5)如何写一个Andorid下自动更新的插件?

    在 <Cordova webapp实战开发:(4)Android环境搭建>中我们搭建好了开发环境,也给大家布置了调用插件的预习作业,做得如何了呢?今天我们来学一下如何自己从头建立一个And ...

  4. 第三次个人作业——关于K米(Andorid)的案例分析

    第三次个人作业--关于K米(Andorid)的案例分析 1.K米简介 官方网址:http://www.ktvme.com/ 2.评测 2.1.上手体验 带着找bug的心态,兴致勃勃地开始体验 K米.打 ...

  5. android:id="@id/resid" , andorid:id="@+id/resid" 的区别

    的区别?android:id="@id/resid"    // 引用现有的资源idandorid:id="@+id/resid"  // 新增一个资源id i ...

  6. Andorid手机振动器(Vibrator)的使用

    标签: android vibrator 震动器 it 分类: Andorid 获取振动器Vibrator实例: Vibrator  mVibrator = (Vibrator) context.ge ...

  7. js判断手机端操作系统(Andorid/IOS)

    非常实用的js判断手机端操作系统(Andorid/IOS),并自动跳转相应下载界面 androidURL = "http://xxx/xxx.apk"; var browser = ...

  8. 小牟Andorid下面MD5具体实现的思路总结

    Android的开发往往需要一定数目demo 从今起MD5一些加密算法提取物 看看是如何实现的 首先,我们必须明确为什么加密? 1 数据安全处理 2 防止数据窃取 3 有效的避免恶意攻击 4 保证文件 ...

  9. andorid之摄像头驱动流程--MTK平台

    原文地址:andorid之摄像头驱动流程--MTK平台 作者:守候心田 camera成像原理: 景物通过镜头生产光学图像投射到sensor表面上,然后转为模拟电信号,经过数模变成数字图像信号,在经过D ...

随机推荐

  1. 【转】 HTMLCollection和NodeList的区别

    1 HTMLCollection类型 下面的每个项目(以及它们指定的属性)都返回 HTMLCollection(基类)或者它的派生类: Document (images, applets, links ...

  2. 自动备份SQL数据库 并删除指定日期之前的备份文件

    /// <summary>        /// 数据备份        /// </summary>        /// public bool DataBackup(st ...

  3. WinForm添加快捷键

    1.    WinForm下给窗体和按钮添加快捷键 设置Enter键要执行的动作:设置FORM的 AcceptButton属性为指定的button按钮. 设置ESC键要执行的动作:设置FORM的Cac ...

  4. mssql2000 身份证号码验证

    CREATE VIEW thisDate --返回当前日期,因为自定义函数中不能使用GETDATE() AS ),) AS aDate )) /*mssql2000 返回值=0,身份证校验正确 1:位 ...

  5. hdu5834

    题目让求得是从任意一点出发可以不回来得到的最大的价值 这应该不算特别水的树形dp了,它不止要从上往下dfs,后来海要重新dfs,根据父亲节点更新儿子节点,算是正常的树形dp中比较简单的吧. 思路: 先 ...

  6. C89和C99区别--简单总结

    (1)对数组的增强 可变长数组 C99中,程序员声明数组时,数组的维数可以由任一有效的整型表达式确定,包括只在运行时才能确定其值的表达式,这类数组就叫做可变长数组,但是只有局部数组才可以是变长的.可变 ...

  7. socket选项总结(setsocketopt)

    功能描述:        获取或者设置与某个套接字关联的选 项.选项可能存在于多层协议中,它们总会出现在最上面的套接字层.当操作套接字选项时,选项位于的层和选项的名称必须给出.为了操作套接字层的选项, ...

  8. Vim命令合集

    1.模式切换 三种模式:命令模式,输入模式,底行模式 命令模式与输入模式之间的切换:i esc 命令模式与底行模式的切换:shift + :  esc 2. 插入 i:在当前字符的左边插入 I:在当前 ...

  9. 发现 git忽略没用

    git rm --cached GuoJiWeb/Properties/PublishProfiles/Profile1.pubxml

  10. 在JSP中使用JavaBean

    //创建一个PersonBean类 public class PersonBean {    private String name;    private int age;    public Pe ...