編輯:Android開發實例
前言
本文講解一下如何在Android平台下播放一個逐幀動畫。逐幀動畫在Android下可以通過代碼和XML文件兩種方式定義,本文都將講到,最後將以一個簡單的Demo來演示兩種方式定義的逐幀動畫的播放。
本文的主要內容:
Android中的逐幀動畫
先來說說什麼是逐幀動畫,逐幀動畫是一種常見的動畫形式(Frame By Frame),其原理是在“連續的關鍵幀”中分解動畫動作,也就是在時間軸的每幀上逐幀繪制不同的內容,使其連續播放而成動畫。 因為逐幀動畫的幀序列內容不一樣,不但給制作增加了負擔而且最終輸出的文件量也很大,但它的優勢也很明顯:逐幀動畫具有非常大的靈活性,幾乎可以表現任何想表現的內容,而它類似與電影的播放模式,很適合於表演細膩的動畫。
在Android中逐幀動畫需要得到AnimationDrawable類的支持,它位於"android.graphics.drawable.AnimationDrawable"包下,是Drawable的間接子類。它主要用來創建一個逐幀動畫,並且可以對幀進行拉伸,把它設置為View的背景即可使用AnimationDrawable.start()方法播放。既然逐幀動畫是需要播放一幀一幀的圖像,所以需要為其添加幀。在Android中提供了兩種方式為AnimationDrawable添加幀:XML定義的資源文件和Java代碼創建,後面再詳細講講這兩種添加幀的方式。
光為AnimationDrawable設置幀還不能完成播放動畫的功能,還需要AnimationDrawable定義好的其他的一些方法來操作逐幀動畫,下面簡單介紹一下AnimationDrawable的常用方法:
使用XML定義的資源文件設置動畫幀
Android下所有的資源文件均要放在/res目錄下,對於動畫幀的資源需要當成一個Drawable,所以需要把它放在/res/Drawable目錄下。而定義逐幀動畫非常簡單,只要在<animation-list.../>元素中使用<item.../>子元素定義動畫的全部幀,並制定各幀的持續時間即可。還可以在<animation-list.../>元素中添加屬性,來設定逐幀動畫的屬性。
例如:
- <?xml version="1.0" encoding="utf-8"?>
- <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false" >
- <!-- 定義一個動畫幀,Drawable為img0,持續時間50毫秒 -->
- <item android:drawable="@drawable/img0" android:duration="50" />
- </animation-list>
定義好逐幀動畫的資源文件之後,只需要使用getResources().getDrawable(int)方法獲取AnimationDrawable示例,然後把它設置為某個View的背景即可。
下面通過一個簡單的Demo,來演示如何播放一個XML定義的逐幀動畫,布局很簡單,一個ImageView來承載逐幀動畫,兩個Button控制播放與停止:
XML幀動畫的資源文件:
- <?xml version="1.0" encoding="utf-8"?>
- <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false" >
- <!-- 定義一個動畫幀,Drawable為img0,持續時間50毫秒 -->
- <item android:drawable="@drawable/img0" android:duration="50" />
- <item android:drawable="@drawable/img1" android:duration="50" />
- <item android:drawable="@drawable/img2" android:duration="50" />
- <item android:drawable="@drawable/img3" android:duration="50" />
- <item android:drawable="@drawable/img4" android:duration="50" />
- <item android:drawable="@drawable/img5" android:duration="50" />
- <item android:drawable="@drawable/img6" android:duration="50" />
- <item android:drawable="@drawable/img7" android:duration="50" />
- <item android:drawable="@drawable/img8" android:duration="50" />
- <item android:drawable="@drawable/img9" android:duration="50" />
- <item android:drawable="@drawable/img10" android:duration="50" />
- <item android:drawable="@drawable/img11" android:duration="50" />
- <item android:drawable="@drawable/img12" android:duration="50" />
- <item android:drawable="@drawable/img13" android:duration="50" />
- <item android:drawable="@drawable/img14" android:duration="50" />
- <item android:drawable="@drawable/img15" android:duration="50" />
- <item android:drawable="@drawable/img16" android:duration="50" />
- <item android:drawable="@drawable/img17" android:duration="50" />
- <item android:drawable="@drawable/img18" android:duration="50" />
- <item android:drawable="@drawable/img19" android:duration="50" />
- <item android:drawable="@drawable/img20" android:duration="50" />
- <item android:drawable="@drawable/img21" android:duration="50" />
- <item android:drawable="@drawable/img22" android:duration="50" />
- <item android:drawable="@drawable/img23" android:duration="50" />
- <item android:drawable="@drawable/img24" android:duration="50" />
- </animation-list>
實現代碼:
- package cn.bgxt.frameanimationdemo;
- import android.app.Activity;
- import android.graphics.drawable.AnimationDrawable;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.ImageView;
- import android.widget.Toast;
- public class ToXMLActivity extends Activity {
- private Button btn_start, btn_stop;
- private ImageView iv_frame;
- private AnimationDrawable frameAnim;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_frameanim);
- btn_start = (Button) findViewById(R.id.btn_start);
- btn_stop = (Button) findViewById(R.id.btn_stop);
- btn_start.setOnClickListener(click);
- btn_stop.setOnClickListener(click);
- iv_frame = (ImageView) findViewById(R.id.iv_frame);
- // 通過逐幀動畫的資源文件獲得AnimationDrawable示例
- frameAnim=(AnimationDrawable) getResources().getDrawable(R.drawable.bullet_anim);
- // 把AnimationDrawable設置為ImageView的背景
- iv_frame.setBackgroundDrawable(frameAnim);
- }
- private View.OnClickListener click = new OnClickListener() {
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.btn_start:
- start();
- break;
- case R.id.btn_stop:
- stop();
- break;
- default:
- break;
- }
- }
- };
- /**
- * 開始播放
- */
- protected void start() {
- if (frameAnim != null && !frameAnim.isRunning()) {
- frameAnim.start();
- Toast.makeText(ToXMLActivity.this, "開始播放", 0).show();
- Log.i("main", "index 為5的幀持續時間為:"+frameAnim.getDuration(5)+"毫秒");
- Log.i("main", "當前AnimationDrawable一共有"+frameAnim.getNumberOfFrames()+"幀");
- }
- }
- /**
- * 停止播放
- */
- protected void stop() {
- if (frameAnim != null && frameAnim.isRunning()) {
- frameAnim.stop();
- Toast.makeText(ToXMLActivity.this, "停止播放", 0).show();
- }
- }
- }
使用Java代碼創建逐幀動畫
在Android中,除了可以通過XML文件定義一個逐幀動畫之外,還可以通過AnimationDrawable.addFrame()方法為AnimationDrawable添加動畫幀,上面已經提供了addFrame()的方法簽名,它可以設置添加動畫幀的Drawable和持續時間。其實沒什麼技術含量,下面通過一個簡單的Demo演示一下。
實現代碼:
- package cn.bgxt.frameanimationdemo;
- import android.app.Activity;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.ColorFilter;
- import android.graphics.drawable.AnimationDrawable;
- import android.graphics.drawable.BitmapDrawable;
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.ImageView;
- import android.widget.Toast;
- public class ToCodeActivity extends Activity {
- private Button btn_start, btn_stop;
- private ImageView iv_frame;
- private AnimationDrawable frameAnim;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_frameanim);
- btn_start = (Button) findViewById(R.id.btn_start);
- btn_stop = (Button) findViewById(R.id.btn_stop);
- btn_start.setOnClickListener(click);
- btn_stop.setOnClickListener(click);
- iv_frame = (ImageView) findViewById(R.id.iv_frame);
- frameAnim =new AnimationDrawable();
- // 為AnimationDrawable添加動畫幀
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img0), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img1), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img2), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img3), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img4), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img5), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img6), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img7), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img8), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img9), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img10), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img11), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img12), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img13), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img14), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img15), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img16), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img17), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img18), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img19), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img20), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img21), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img22), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img23), 50);
- frameAnim.addFrame(getResources().getDrawable(R.drawable.img24), 50);
- frameAnim.setOneShot(false);
- // 設置ImageView的背景為AnimationDrawable
- iv_frame.setBackgroundDrawable(frameAnim);
- }
- private View.OnClickListener click = new OnClickListener() {
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.btn_start:
- start();
- break;
- case R.id.btn_stop:
- stop();
- break;
- default:
- break;
- }
- }
- };
- /**
- * 開始播放
- */
- protected void start() {
- if (frameAnim != null && !frameAnim.isRunning()) {
- frameAnim.start();
- Toast.makeText(ToCodeActivity.this, "開始播放", 0).show();
- }
- }
- /**
- * 停止播放
- */
- protected void stop() {
- if (frameAnim != null && frameAnim.isRunning()) {
- frameAnim.stop();
- Toast.makeText(ToCodeActivity.this, "停止播放", 0).show();
- }
- }
- }
其實上面兩個Demo實現的都是一種效果,是一個子彈擊中牆體的逐幀動畫效果,下面展示一下Demo的運行效果:
源碼下載
JSON代表JavaScript對象符號。它是一個獨立的數據交換格式,是XML的最佳替代品。本章介紹了如何解析JSON文件,並從中提取所需的信息。Android提供了四個
在Android程序中很多客戶端軟件和浏覽器軟件都喜歡用Tab分頁標簽來搭建界面框架。讀者也許會馬上想到使用TabHost 與 TabActivity的組合,其實
Fragment Android是在Android 3.0 (API level 11)開始引入Fragment的。 可以把Fragment想成Activity中
步驟:分兩步 一、usb連接: 在Ubuntu掛載使用MTP設備步驟如下: 1.將MTP設備連接至PC機 2.如果是第一次使用MTP設備需要安裝以下軟件,否則可以