2014-10-31Android學習------序列幀動畫,開始,結束監聽的解決--------GIF動畫實現
寫一篇文章很辛苦啊!!!
轉載請註明,聯絡請郵件[email protected]
我學習Android都是結合原始碼去學習,這樣比較直觀,非常清楚的看清效果,覺得很好,今天的學習原始碼是網上找的個AnimationTest 原始碼 百度搜就知道很多下載的地方 網上原始碼的名字叫:序列幀動畫,開始,結束監聽的解決.zip
監聽事件非常的常見 也經常用 我們一般都是利用系統裡面的方法去實現
監聽事件可以是觸控(一般是按下,拖動,鬆開) 可以是點選(點選事件是指你設定了一個按鈕或者圖片等)
但是當你自己去定義一個View的時候,這個時候介面就需要你自己去定義了
系統自定義定義的widget都是有相應的監聽事件的處理,但是你自己定義了一個widget 就需要去自己寫出來了,
這節將的就是當我們繼承View實現了動畫的展示,但是我們需要去監聽這個動畫並有操作該怎麼辦?該怎麼去寫這樣的函式
其實它的原理跟前面的文章:26個字母的列表實現是一樣的 點選我檢視
根據前面的例子我們知道一般步驟是這樣的:
1.自己定義一個類 讓它繼承Android.view.View
2.過載這個類的建構函式,然後處理OnDraw()函式
3.如果我們想要自己定義的檢視能夠被監聽,是需要再類中新增監聽介面(定義方法不實現)
4.如果想要這個自定義的檢視實現監聽,在activity中,那麼首先需要把它 放在 佈局檔案中,也就是你需要在layout中有定義
做法一般是這樣的:
<com.wust.citylist.activity.MyLetterListView
android:id="@+id/cityLetterListView"
android:layout_width="30dip"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:background="#40000000" />
看到沒有 我們只關心 這句話:com.wust.citylist.activity.MyLetterListView這樣做就把我們自己定義的檢視當做一個控制元件顯示在佈局上了,這個時候我們就可以去處理它的監聽事件了
5.接下來就在實現這個佈局檔案的activity類中去實現這個介面中的函式就可以了 也就是過載
上面的步驟應該說的夠清楚了,接下來我們就來看看 幀動畫事件的監聽處理
一. 定義自己的檢視
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.widget.ImageView;
public class AnimationImageView extends ImageView {
public AnimationImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public AnimationImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public AnimationImageView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public interface OnFrameAnimationListener{
/**
* 動畫開始播放後呼叫
*/
void onStart();
/**
* 動畫結束播放後呼叫
*/
void onEnd();
}
/**
* 不帶動畫監聽的播放
* @param resId
*/
public void loadAnimation(int resId){
setImageResource(resId);
AnimationDrawable anim = (AnimationDrawable)getDrawable();
anim.start();
}
/**
* 帶動畫監聽的播放
* @param resId
* @param listener
*/
public void loadAnimation(int resId, final OnFrameAnimationListener listener) {
setImageResource(resId);
AnimationDrawable anim = (AnimationDrawable)getDrawable();
anim.start();
if(listener != null){
// 呼叫回撥函式onStart
listener.onStart();
}
// 計算動態圖片所花費的事件
int durationTime = 0;
for (int i = 0; i < anim.getNumberOfFrames(); i++) {
durationTime += anim.getDuration(i);
}
// 動畫結束後
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if(listener != null){
// 呼叫回撥函式onEnd
listener.onEnd();
}
}
}, durationTime);
}
}
code說明:
1.第一個這個類是繼承ImageView ,上篇文章我們是直接繼承View的
2.建構函式 處理 這裡不需要我們關係:右鍵 source ->generate constructors from superclass.... 然後全部勾選就可以了
3.監聽事件的介面:
public interface OnFrameAnimationListener{
/**
* 動畫開始播放後呼叫
*/
void onStart();
/**
* 動畫結束播放後呼叫
*/
void onEnd();
}
這個就是像我們的生命週期一樣,當建立之後可以做哪些操作,結束之後有可以做哪些操作,至於怎麼操作需要你自己再去重寫
4.當這些做完了,我們就需要把動畫載入到檢視上去了,而載入到檢視上是怎麼實現的呢?
它是先從檔案中把圖片載入到動畫這個類上,然後再有這個類放在檢視上,就想上篇文章,我們定義一個Movie類一樣,不過這裡是 AnimationDrawable,
首先我們來看看官方API是怎麼樣介紹的:
Class Overview
An object used to create frame-by-frame animations, defined by a series of Drawable objects, which can be used as a View object's background.
The simplest way to create a frame-by-frame animation is to define the animation in an XML file, placed in the res/drawable/ folder, and set it as the background to a View object. Then, call run()
to
start the animation.
An AnimationDrawable defined in XML consists of a single <animation-list>
element, and a series of nested <item>
tags. Each item defines a frame
of the animation.
該物件是用來建立序列幀動畫的(一幀接一幀動畫),這些系列幀動畫是通過一系列可以繪製的物件來定義的,
而這些可以繪製的物件能夠被作為一個View物件的背景。
建立系列幀動畫最簡單的方法就是在XML檔案中去定義動畫,把它們放在資料夾下,res/drawable/folder(folder是可以自己定義的,也可以不要這個檔案),把他們設定為一個檢視物件的背景。然後,呼叫函式run()去啟動動畫
一個AnimationDrawable(可繪製動畫) 是在XML中定義的,它通常是這樣定義的(由下面的這些組成):在xml檔案中
根節點是<animation-list>,子節點是<item>,每一個<item>定義動畫的的一幀(也就是一幀動畫)
看看官方給出的例子:
See the example below.
spin_animation.xml file in res/drawable/ folder:
<!-- Animation frames are wheel0.png -- wheel5.png files inside the res/drawable/ folder --><animation-listandroid:id="selected"android:oneshot="false"><itemandroid:drawable="@drawable/wheel0"android:duration="50"/><itemandroid:drawable="@drawable/wheel1"android:duration="50"/><itemandroid:drawable="@drawable/wheel2"android:duration="50"/><itemandroid:drawable="@drawable/wheel3"android:duration="50"/><itemandroid:drawable="@drawable/wheel4"android:duration="50"/><itemandroid:drawable="@drawable/wheel5"android:duration="50"/></animation-list>
Here is the code to load and play this animation.
// Load the ImageView that will host the animation and// set its background to our AnimationDrawable XML resource.ImageView img =(ImageView)findViewById(R.id.spinning_wheel_image); img.setBackgroundResource(R.drawable.spin_animation);// Get the background, which has been compiled to an AnimationDrawable object.AnimationDrawable frameAnimation =(AnimationDrawable) img.getBackground();// Start the animation (looped playback by default). frameAnimation.start()注意到:
// Get the background, which has been compiled to an AnimationDrawable object.AnimationDrawable frameAnimation =(AnimationDrawable) img.getBackground();
()Return the view's drawable, or null if no drawable has been assigned. |
XML Attributes | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Attribute Name | Related Method | Description | |||||||||
Reference to a drawable resource to use for the frame. | |||||||||||
Amount of time (in milliseconds) to display this frame. | |||||||||||
If true, the animation will only run a single time and then stop. | |||||||||||
If true, allows the drawable's padding to change based on the current state that is selected. | |||||||||||
Provides initial visibility state of the drawable; the default value is false. |
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true" >
<item
android:drawable="@drawable/besg00042"
android:duration="150">
</item>
<item
android:drawable="@drawable/besg00041"
android:duration="150">
</item>
</animation-list>
這樣做了之後,我們再回來這個函式的處理: 看下面的函式 public void loadAnimation(int resId){// 引數resID是資原始檔對應的id setImageResource(resId);//用這個id對應的檔案來佈置ImageView檢視的內容,也就是當前我們繼承的AnimationView類, AnimationDrawable anim = (AnimationDrawable)getDrawable();//得到一個AnimationDrawable物件 anim.start();//然後啟動動畫 } 上面的函式就是上面的,如果沒有監聽事件,就這樣寫,但是如果有監聽事件的話,我們是怎麼讓這些動畫載入到檢視上去的呢? 我們繼續往下分析: /**
* 帶動畫監聽的播放
* @param resId
* @param listener 注意到這裡一個final來修飾這個引數,因為我們的介面是內部定義的,如果不這樣 * 定義是會出錯的。
*/
public void loadAnimation(int resId, final OnFrameAnimationListener listener) {
setImageResource(resId);
AnimationDrawable anim = (AnimationDrawable)getDrawable();
anim.start(); //到這裡為止,思路跟沒有監聽的思路是一致的,那麼有了監聽事件就繼續往下走
if(listener != null){//如果有監聽事件的話,那麼馬上去呼叫監聽事件的處理函式,也就是監聽被 //觸發了
// 呼叫回撥函式onStart
listener.onStart();//這個函式是介面中定義但沒有被實現的方法,到底要執行什麼,需要去 //activity類中去過載它
}
// 計算動態圖片所花費的時間
int durationTime = 0;
for (int i = 0; i < anim.getNumberOfFrames(); i++) {
durationTime += anim.getDuration(i);
}
// 動畫結束後
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if(listener != null){
// 呼叫回撥函式onEnd
listener.onEnd();
}
}
}, durationTime);
}
public int getDuration (int i)
Returns
- The duration in milliseconds of the frame at the specified index
public int getNumberOfFrames ()
Returns
- The number of frames in the animation
android:id="@+id/anim_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
三。當在main.xml定義好之後,我們需要去處理activity類了: 1.在onCreate(Bundle )類中先去載入這個佈局 @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);//載入佈局
initView();//初始化 這裡主要是找到佈局檔案中的各個控制元件
setListener();//設定監聽事件 這種寫法就是讓當前的類去實現implements OnClickListener
}
private void initView() {
// TODO Auto-generated method stub
anim_view = (AnimationImageView) findViewById(R.id.anim_view);//找到這個控制元件
attack = (Button) this.findViewById(R.id.attack);
defense = (Button) this.findViewById(R.id.defense);
// 載入預設的動態圖
anim_view.loadAnimation(R.drawable.anim_idle);首先是讓當前的檢視就有動畫,初始化動畫
}
private void setListener() {
// TODO Auto-generated method stub
attack.setOnClickListener(this);
defense.setOnClickListener(this);
}
接下來就是用按鈕的點選事件來實現對動畫的監聽: @Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.attack:
// 如果點選了該按鈕,載入帶監聽的動態圖 播放攻擊動作 // 注意到這個引數,是一個內部類的形式
anim_view.loadAnimation(R.drawable.anim_attack,
new OnFrameAnimationListener() {
@Override
public void onStart() {
// 動畫剛播放時 // 可以載入你自己的程式碼,也即是使用者點選了攻擊按鈕,你想幹什麼
}
@Override
public void onEnd() {
// 動畫結束播放時
// 還原回預設動態圖 讓檢視的背景重新返回初始化時設定的樣子
anim_view.loadAnimation(R.drawable.anim_idle);
}
});
break;
case R.id.defense:
// 載入帶監聽的動態圖 防禦動作
anim_view.loadAnimation(R.drawable.anim_defense,
new OnFrameAnimationListener() {
@Override
public void onStart() {
// 動畫剛播放時
}
@Override
public void onEnd() {
// 動畫結束播放時
// 還原回預設動態圖
anim_view.loadAnimation(R.drawable.anim_idle);
}
});
break;
}
}
至此activity也就完成了,接下來去配置下清單檔案就可以部署了, 我們看看效果圖:
關於動畫還有其他的方式,這裡就先不講了,下次有機會再學習。
相關推薦
2014-10-31Android學習------序列幀動畫,開始,結束監聽的解決--------GIF動畫實現
寫一篇文章很辛苦啊!!! 轉載請註明,聯絡請郵件[email protected] 我學習Android都是結合原始碼去學習,這樣比較直觀,非常清楚的看清效果,覺得很好,今天的學習原始碼是網上找的個AnimationTest 原始碼 百度搜就知道很多下載的
2014-10-27Android學習------SQLite資料庫操作(二)-----資料庫的建立--SQLiteHelper extends SQLiteOpenHelper
上篇有篇文章講了資料庫的操作 條件是:資料庫已經建好的了,我們只需要從裡面獲取資料(查詢)就可以了, 現在我們來看看第二種資料庫的操作: class SQLiteHelper extends SQLiteOpenHelper 封裝一個繼承SQLiteOpenHelpe
Android學習之自定義TextWatcher來監聽文字最大輸入字數
開發中有種很可能會遇到的需求就是限制EditText的文字輸入字數,例如微博就限制140字,如果只是限制輸入的字數的話很簡單,EditText有個屬性叫android:maxLength,設定140就
【學習筆記】Bootstrap外掛 滾動監聽+彈出框+選項卡
--滾動監聽 依賴導航元件步驟:1.寫一個導航元件2.data-target="#test"執行滾動監聽的目標 data-spy="scroll" 向想要監聽的元素 新增滾動監聽 <nav id="test" class="navbar navbar-defa
js配合錨點實現動畫滾動與監聽
這個技能感覺不錯,配合bootstrap寫出的。下面是乾貨: ul 的每個li的每個a中的href指向錨點目標,比如說<li class="active"><a href="#index">Home</a></li&g
特效序列幀動畫,可指定開始和結束點
直接貼程式碼: Shader "James/FX/MeshFrame" { Properties { [Enum(Add, 1, Blend, 10)] _DstBlend ("Blend Mode", Float) = 1 _Ma
關於在unity中使用序列幀動畫
atime highlight ++ switch ati 是你 一秒 tor 報錯 //動畫數組 public object[] anim; //限制一秒多少幀 public float fps = 30; //幀序列 priv
Html5 序列幀動畫
下一個 XML default idt 毫秒 meta document etc array <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <he
從零開始學習前端開發 — 15、CSS3變形基礎過渡、動畫
steps 方式 css3動畫 rec step round 保持 start radius 一、css3過渡 語法: transition: 過渡屬性 過渡時間 延遲時間 過渡方式; 1.過渡屬性(transition-property) 取值:all 所有發生變化的cs
UV序列幀動畫
sub sam ble parent image png ons custom 分享圖片 通過上圖實現一個火焰的序列幀動畫(使用UV實現美術只需要出一張圖,而不用每個火焰狀態出一張圖,節省了內存)。 shader如下: Shader "Custom/UVAnimatio
Cocos2d-x 3.x序列幀動畫
vector 序列幀 bash cpp ams with 序列 object -s Animation : 一個給精靈對象執行的幀動畫對象。 Animate:是將動畫包裝成動作的類。 AnimationCache:管理動畫的單例。 簡介 Animat
學習筆記:從0開始學習大資料-10. hive安裝部署
1. 下載 wget http://archive.cloudera.com/cdh5/cdh/5/hive-1.1.0-cdh5.15.1.tar.gz 2.解壓 tar -zxvf hive-1.1.0-cdh5.15.1.tar.gz 3. hive的元資料(如表名,列
WPF 序列幀動畫
直接上程式碼 private void LoadPics() { try { _storyboard = new Storyboard(); for (int i =
【2014.10】神經網路中的深度學習綜述
本綜述的主要內容包括: 神經網路中的深度學習簡介 神經網路中面向事件的啟用擴充套件表示法 信貸分配路徑(CAPs)的深度及其相關問題 深度學習的研究主題 有監督神經網路/來自無監督神經網路的幫助 FNN與RNN中用於強化學習RL
css精靈圖寫序列幀動畫
最近寫一個H5要求序列幀動畫比較多,但是卻僅僅是作為裝飾,而不對其進行操作,為了減小記憶體以及更好的效能選擇了css動畫+css精靈圖的方式。 1.找工具製作css精靈圖。 聽說Win系統的css sprite很好用,可惜m
楓葉天空Cocos2d-x3.0系列教程二 序列幀動畫
更新日誌: 2014-01-31 增加了cocoStudio動畫編輯器的說明 內容概述: 從今天開始,我們就正式進入cocos2d-x3.0的開發教程了,本篇的核心內容是序列幀動畫。 準備工作 1、首先我們建立一個新的場景類,作為我們本系列教程的一
Cocos2d-序列幀動畫
基礎原理 Cocos2d-x中,動畫的具體內容是依靠精靈顯示出來的,為了顯示動態圖片,我們需要不停切換精靈顯示的內容,通過把靜態的精靈變為動畫播放器從而實現動畫效果。動畫由幀組成,每一幀都是一個紋理,我們可以使用一個紋理序列來建立動畫。 我們使用Animat
Unity3D學習筆記(10)—— 遊戲序列化
這期內容有關遊戲的序列化,什麼是序列化呢?額...就是遊戲的內容可以輸出成文字格式,或者遊戲的內容可以從文字中解析獲得。現在的遊戲幾乎離不開序列化,只要有存檔機制的遊戲必然會序列化,並且遊戲的每次啟動都會讀取序列文字。另外遊戲的更新也和序列化緊密相關,比如L
AM335x(TQ335x)學習筆記——u-boot-2014.10移植
最近移植了下u-boot-2014.10到TQ335x,如果基於am335x evm進行移植,需要修改的地方並不多。 由於TI的am335x evm開發使用了一個eeprom儲存了板載配置資訊,用來區分不同板子的型號的,而TQ335x沒有這個eeprom,因此,需要修改ee
關於cocos2d序列幀動畫plist檔案的建立
轉載請註明出處 用過的人都知道,cocos2d的動畫編輯器是多麼的坑,自從cocos2d支援Animation後,開始使用Animation動畫了。關於Animation的使用網上也有很多,但是我看了一下,主流的就是兩種方法,一是:手動新增,將plist檔案裡的精靈幀一