萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> 安卓開發 >> Android動畫框架的講解

Android動畫框架的講解

本文導航

1、首頁2、窗口坐標系-2

這是我們為大家提供的一篇關於Android動畫框架的講解的文章,接下來就讓我們一起來了解一下吧!

Android 平台提供了一套完整的動畫框架,使得開發者可以用它來開發各種動畫效果,本文將向讀者闡述 Android 的動畫框架是如何實現的。 任何一個框架都有其優勢和局限性,只有明白了其實現原理,開發者才能知道哪些功能可以利用框架來實現,哪些功能須用其他途徑實現。Android 平台提供了兩類動畫,一類是 Tween 動畫,即通過對場景裡的對象不斷做圖像變換 ( 平移、縮放、旋轉 ) 產生動畫效果;第二類是 Frame 動畫,即順序播放事先做好的圖像,跟電影類似。本文是由兩部分組成的有關 Android 動畫框架詳解的第一部分原理篇, 主要分析 Tween 動畫的實現原理, 最後簡單介紹在 Android 中如何通過播放 Gif 文件來實現動畫。我們先看一下動畫示例來一點感性認識。

Android 動畫使用示例

使用動畫示例程序的效果是點擊按鈕,TextView 旋轉一周。讀者也可以參看 Apidemos 中包 com.example.android.apis.animationview 下面的 Transition3d 和 com.example.android.apis.view 下面的 Animation1/Animation2/Animation3 示例代碼。

清單 1. 代碼直接使用動畫

package com.ray.animation;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.animation.AccelerateDecelerateInterpolator;

import android.view.animation.Animation;

import android.view.animation.RotateAnimation;

import android.widget.Button;

public class TestAnimation extends Activity implements OnClickListener{

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Button btn =(Button)findViewById(R.id.Button);

btn.setOnClickListener(this);

}

public void onClick(View v){

Animation anim=null;

anim=new?RotateAnimation(0.0f,+360.0f);

anim.setInterpolator(new AccelerateDecelerateInterpolator());

anim.setDuration(3000);

findViewById(R.id.TextView01).startAnimation(anim);

}

}

復制代碼

使用 XML 文件方式,在打開 Eclipse 中新建的 Android 工程的 res 目錄中新建 anim 文件夾,然後在 anim 目錄中新建一個 myanim.xml( 注意文件名小寫 ),內容如下 :

圖 1. 使用 xml 文件方式

Android動畫框架

其中的 java 代碼如下:

package com.ray.animation;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.animation.Animation;

import android.view.animation.AnimationUtils;

import android.widget.Button;

import android.widget.TextView;

public class TestAnimation extends Activity implements OnClickListener{

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Button btn =(Button)findViewById(R.id.Button01);

btn.setOnClickListener(this);

}

@Override

public void onClick(View v){

Animation anim=AnimationUtils.loadAnimation(this,R.anim.my_rotate_action);

findViewById(R.id.TextView01).startAnimation(anim);

}

}

復制代碼

Android 動畫框架原理

現有的 Android 動畫框架是建立在 View 的級別上的,在 View 類中有一個接口 startAnimation 來使動畫開始,startAnimation 函數會將一個 Animation 類別的參數傳給 View,這個 Animation 是用來指定我們使用的是哪種動畫,現有的動畫有平移,縮放,旋轉以及 alpha 變換等。如果需要更復雜的效果,我們還可以將這些動畫組合起來,這些在下面會討論到。

要了解 Android 動畫是如何畫出來的,我們首先要了解 Android 的 View 是如何組織在一起,以及他們是如何畫自己的內容的。每一個窗口就是一棵 View 樹,下面以我們寫的 android_tabwidget_tutorial.doc 中的 tab 控件的窗口為例,通過 android 工具 hierarchyviewer 得到的窗口 View Tree 如下圖 1 所示:

圖 2. 界面 View 結構圖

Android動畫框架

圖 3. 界面 View 結構和顯示對應圖

Android動畫框架

其實這個圖不是完整的,沒有把 RootView 和 DecorView 畫出來,RootView 只有一個孩子就是 DecorView,這裡整個 View Tree 都是 DecorView 的子 View,它們是從 android1.5/frameworks/base/core/res/res/layout/screen_title.xml 這個 layout 文件 infalte 出來的,感興趣的讀者可以參看 frameworks\policies\base\phone\com\android\internal\policy\Imp\PhoneWindow.java 中

generateLayout 函數部分的代碼。我們可以修改布局文件和代碼來做一些比較 cool 的事情,如象 Windows 的縮小 / 關閉按鈕等。標題窗口以下部分的 FrameLayou 就是為了讓程序員通過 setContentView 來設置用戶需要的窗口內容。因為整個 View 的布局就是一棵樹,所以繪制的時候也是按照樹形結構遍歷來讓每個 View 進行繪制。ViewRoot.java 中的 draw 函數准備好 Canvas 後會調用 mView.draw(canvas),其中 mView 就是調用 ViewRoot.setView 時設置的 DecorView。然後看一下 View.java 中的 draw 函數:

遞歸的繪制整個窗口需要按順序執行以下幾個步驟:

繪制背景;

如果需要,保存畫布(canvas)的層為淡入或淡出做准備;

繪制 View 本身的內容,通過調用 View.onDraw(canvas) 函數實現,通過這個我們應該能看出來 onDraw 函數重載的重要性,onDraw 函數中繪制線條 / 圓 / 文字等功能會調用 Canvas 中對應的功能。下面我們會 drawLine 函數為例進行說明;

繪制自己的孩子(通常也是一個 view 系統),通過 dispatchDraw(canvas) 實現,參看 ViewGroup.Java 中的代碼可知,dispatchDraw->drawChild->child.draw(canvas) 這樣的調用過程被用來保證每個子 View 的 draw 函數都被調用,通過這種遞歸調用從而讓整個 View 樹中的所有 View 的內容都得到繪制。在調用每個子 View 的 draw 函數之前,需要繪制的 View 的繪制位置是在 Canvas 通過 translate 函數調用來進行切換的,窗口中的所有 View 是共用一個 Canvas 對象

如果需要,繪制淡入淡出相關的內容並恢復保存的畫布所在的層(layer)

繪制修飾的內容(例如滾動條),這個可知要實現滾動條效果並不需要 ScrollView,可以在 View 中完成的,不過有一些小技巧,具體實現可以參看我們的 TextViewExample 示例代碼

當一個 ChildView 要重畫時,它會調用其成員函數 invalidate() 函數將通知其 ParentView 這個 ChildView 要重畫,這個過程一直向上遍歷到 ViewRoot,當 ViewRoot 收到這個通知後就會調用上面提到的 ViewRoot 中的 draw 函數從而完成繪制。

View::onDraw() 有一個畫布參數 Canvas, 畫布顧名思義就是畫東西的地方,Android 會為每一個 View 設置好畫布,View 就可以調用 Canvas 的方法,比如:drawText, drawBitmap, drawPath 等等去畫內容。每一個 ChildView 的畫布是由其 ParentView 設置的,ParentView 根據 ChildView 在其內部的布局來調整 Canvas,其中畫布的屬性之一就是定義和 ChildView 相關的坐標系,默認是橫軸為 X 軸,從左至右,值逐漸增大,豎軸為 Y 軸,從上至下,值逐漸增大 , 見下圖 :

copyright © 萬盛學電腦網 all rights reserved