1. 程式人生 > >補間動畫詳解一 基類Animation

補間動畫詳解一 基類Animation

補間動畫(Tween animation)是通過在兩個關鍵幀之間補充漸變的動畫效果來實現的。

Android系統提供了四個補間動畫的類,分別是AlphaAnimationRotateAnimationScaleAnimationTranslateAnimation,另外還有一個能夠把多個動畫組合起來的AnimationSet類,這些類都有一個共同的基類Animation。

Animation類官方文件:
https://developer.android.com/reference/android/view/animation/Animation.html

類圖:


一、Animation介紹

Animation是一個抽象類,無法直接使用,通常使用的是它的直接子類。

public abstract class Animation implements Cloneable {
}

Animation類定義了一些與動畫相關的變數,子類可以直接使用。
/**
 * 一個動畫週期的持續時間,以毫秒為單位。
 */
long mDuration;

/**
 * 動畫開始執行的延時時長。如果大於0,動畫的執行時間為startTime+startOffset。
 */
long mStartOffset;

/**
 * 設定為true時,將保持動畫開始前的狀態。預設值為true。
 */
boolean mFillBefore = true;

/**
 * 設定為true時,將保持動畫結束時的狀態。預設值為false。
 */
boolean mFillAfter = false;

/**
 * 設定為true時,將應用mFillBefore的值;否則,忽視mFillBefore的值。預設值為false。
 */
boolean mFillEnabled = false;

/**
 * 動畫重複的次數。
 */
int mRepeatCount = 0;

/**
 * 動畫的重複型別,取值為RESTART(從頭播放)或REVERSE(倒序回放)。
 */
int mRepeatMode = RESTART;

/**
 * 表示動畫在執行期間,被設定動畫的內容在Z軸上的順序。
 * 取值範圍ZORDER_NORMAL(保持不動)、ZORDER_TOP(在所有其他內容的頂部)、ZORDER_BOTTOM(在所有其他內容的底部),預設為ZORDER_NORMAL
 */
private int mZAdjustment;

/**
 * 動畫的背景色。
 */
private int mBackgroundColor;

/**
 * 如果設定為true,並且動畫窗體有一個桌布的話,那麼動畫只會應用給窗體,桌布是靜止不動的。預設值為false。
 */
private boolean mDetachWallpaper = false;

/**
 * 插值器,用來修飾動畫效果。
 */
Interpolator mInterpolator;

同時也有一些常量,用來給特定的變數賦值。
/**
 * mRepeatCount設定為INFINITE,表示動畫無限迴圈。
 */
public static final int INFINITE = -1;

/**
 * mRepeatMode設定為RESTART,表示動畫結束後從頭開始執行。
 */
public static final int RESTART = 1;

/**
 * mRepeatMode設定為REVERSE,表示動畫結束後反過來執行。
 */
public static final int REVERSE = 2;

/**
 * setStartTime()傳入該值時,動畫將在第一次呼叫getTransformation(long, Transformation)時開始執行。
 */
public static final int START_ON_FIRST_FRAME = -1;

/**
 * 具體的座標值。
 */
public static final int ABSOLUTE = 0;

/**
 * 相對自身的座標值。
 */
public static final int RELATIVE_TO_SELF = 1;

/**
 * 相對父容器的座標值。
 */
public static final int RELATIVE_TO_PARENT = 2;

/**
 * mZAdjustment設定為ZORDER_NORMAL,表示內容在Z軸保持不動。
 */
public static final int ZORDER_NORMAL = 0;

/**
 * mZAdjustment設定為ZORDER_TOP,表示內容的Z軸方向在所有其他內容的頂部。
 */
public static final int ZORDER_TOP = 1;

/**
 * mZAdjustment設定為ZORDER_BOTTOM,表示內容的Z軸方向在所有其他內容的底部。
 */
public static final int ZORDER_BOTTOM = -1;

這些成員變數在構造方法中被初始化。
public Animation(Context context, AttributeSet attrs) {
    TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Animation);

    setDuration((long) a.getInt(com.android.internal.R.styleable.Animation_duration, 0));
    setStartOffset((long) a.getInt(com.android.internal.R.styleable.Animation_startOffset, 0));

    setFillEnabled(a.getBoolean(com.android.internal.R.styleable.Animation_fillEnabled, mFillEnabled));
    setFillBefore(a.getBoolean(com.android.internal.R.styleable.Animation_fillBefore, mFillBefore));
    setFillAfter(a.getBoolean(com.android.internal.R.styleable.Animation_fillAfter, mFillAfter));

    setRepeatCount(a.getInt(com.android.internal.R.styleable.Animation_repeatCount, mRepeatCount));
    setRepeatMode(a.getInt(com.android.internal.R.styleable.Animation_repeatMode, RESTART));

    setZAdjustment(a.getInt(com.android.internal.R.styleable.Animation_zAdjustment, ZORDER_NORMAL));

    setBackgroundColor(a.getInt(com.android.internal.R.styleable.Animation_background, 0));

    setDetachWallpaper(a.getBoolean(com.android.internal.R.styleable.Animation_detachWallpaper, false));

    final int resID = a.getResourceId(com.android.internal.R.styleable.Animation_interpolator, 0);

    a.recycle();

    if (resID > 0) {
        setInterpolator(context, resID);
    }

    ensureInterpolator();
}
上面的每一個成員變數都有與之對應的set方法和xml屬性。以成員變數mDuration為例,它的set方法為setDuration(),xml屬性為android:duration。

Animation類內部定義了動畫的監聽器AnimationListener,通過呼叫setAnimationListener()方法來設定監聽器。
AnimationListener mListener;

/**
 * 設定動畫的監聽
 */
public void setAnimationListener(AnimationListener listener) {
    mListener = listener;
}

/**
 * 動畫的監聽
 */
public static interface AnimationListener {
    /**
     * 動畫開始時回撥。
     */
    void onAnimationStart(Animation animation);

    /**
     * 動畫結束時回撥。
     * 但是當動畫重複次數被設定為INFINITE的時候,該方法不會回撥。
     */
    void onAnimationEnd(Animation animation);

    /**
     * 動畫重複時回撥。
     */
    void onAnimationRepeat(Animation animation);
}

Animation類是通過applyTransformation()方法來處理動畫變化的過程。
protected void applyTransformation(float interpolatedTime, Transformation t) {
}
可以看到,在Animation類中applyTransformation()方法是空的,具體實現由它的四個子類來完成。每個動畫實現類都過載了Animation類的applyTransformation()方法,該方法把一些屬性組裝成一個Transformation類,該方法會被getTransformation()方法呼叫。
在動畫的執行過程中,會反覆的呼叫applyTransformation()方法。每次呼叫引數interpolatedTime值都會變化,該引數從0.0遞增為1.0,當該引數為1.0時表示動畫結束。Transformation類封裝了矩陣Matrix和透明度Alpha值,通過引數Transformation來設定Matrix和Alpha,實現各種效果。

如果我們需要實現自己的動畫類,需要下面兩個步驟:
(1).繼承Animation類。
(2).實現applyTransformation()方法。

一、Animation執行過程

在啟動動畫時,一般是呼叫View類的startAnimation(anim)方法。
先從View類開始看起。

public void startAnimation(Animation animation) {
    animation.setStartTime(Animation.START_ON_FIRST_FRAME);
    setAnimation(animation);
    invalidateParentCaches();
    invalidate(true);
}

protected Animation mCurrentAnimation = null;

public void setAnimation(Animation animation) {
    mCurrentAnimation = animation;
    // other code ......
}
在startAnimation()方法內部,先呼叫setAnimation()方法給成員變數mCurrentAnimation賦值,然後它呼叫invalidate()來重繪自己。

接下來進入draw()方法。
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
    // other code ......
    final Animation a = getAnimation();
    if (a != null) {
        more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired);
    }
    // other code ......
}

public Animation getAnimation() {
    return mCurrentAnimation;
}

private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime,
            Animation a, boolean scalingRequired) {
    // other code ......
    boolean more = a.getTransformation(drawingTime, t, 1f);
    // other code ......
}
在draw()方法內部呼叫了View類的applyLegacyAnimation(),而applyLegacyAnimation()內部又呼叫了Animation類的getTransformation(long,Transformation,float)方法。

再次回到Animation類中,會發現最終在getTransformation()方法中呼叫了applyTransformation()方法,實現各種動畫效果。
public boolean getTransformation(long currentTime, Transformation outTransformation,
    float scale) {
    mScaleFactor = scale;
    return getTransformation(currentTime, outTransformation);
}

public boolean getTransformation(long currentTime, Transformation outTransformation) {
    // other code ......
    applyTransformation(interpolatedTime, outTransformation);
    // other code ......
}

相關推薦

動畫 Animation

補間動畫(Tween animation)是通過在兩個關鍵幀之間補充漸變的動畫效果來實現的。 Android系統提供了四個補間動畫的類,分別是AlphaAnimation、RotateAnimation、ScaleAnimation和TranslateAnimation,另

android之逐幀,動畫

在android的世界中有三種動畫,它們就是逐幀動畫,補間動畫,屬性 動畫。接下來我就分別演示下三種動畫的簡單用法。 各動畫的定義: 逐幀動畫:就是短時間切換圖片,讓人們肉眼看起來是連續的,其實就是播放一組圖片。就相當於gif圖片的生成、還有我們小時候

Android開發——動畫使用篇章(幀動畫動畫)(

Android 動畫分為 view動畫,幀動畫,屬性動畫,本片文章是參考多篇動畫介紹部落格,總結動畫使用API,使用場景。適合日常開發 搬磚使用。 幀動畫 幀動畫是最容易實現的一種動畫,這種動畫更多的依賴於完善的UI資源,他的原理就是將一張張單獨的圖片連貫的進行播放,從而在視覺上

OkHttp3原始碼(Request)

           上次在哪篇部落格看到這句話,我們不重複造輪子不表示我們不需要知道輪子該怎麼造及如何更好的造,我覺得很有道理 對於用到專案的某個開源專案我們不應該只停留在會用的階段,廢話不多說,直接開始okhttp原始碼的學習之路         從上至下我們先從Re

【Android 動畫動畫動畫

前言 :之前很早就想寫寫Android 的動畫,最近剛好有時間,大概聊一聊安卓動畫。 我個人習慣將動畫分為:補間動畫(透明度、旋轉、位移、縮放)、幀動畫、和屬性動畫,這一篇,我們先說說補間動畫。 補間動畫這個詞出於flash,在兩個關鍵幀(可以理解成動畫開始和結束)中間需要做“補

Android 動畫TweenAnimation

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:duration

三:python 對象:數字(上)

結果 dom 運行 精度 升級 方法 函數 般的 代碼 一:python 的數字類型: a)整數和浮點數 b)復數 c)固定精度的十進制數 d)有理分數 e)集合 f)布爾類型 g)無窮的整數精度 h)各種數字內置函數和模塊 二:各種數字類型的詳解   1,數字常量:pyt

python的方法,普通方法和靜態方法

http 接下來 方法調用 pytho 類和實例 訪問類 靜態 都是 com   首先形式上的區別,實例方法隱含的參數為類實例self,而類方法隱含的參數為類本身cls。 靜態方法無隱含參數,主要為了類實例也可以直接調用靜態方法。   所以邏輯上,類方法被類調用,實例方法

Flutter 動畫

本文主要介紹了動畫的原理相關概念,對其他平臺的動畫做了一個簡要的梳理,並簡要的介紹了Flutter動畫的一些知識。 1. 動畫介紹 動畫對於App來說,非常的重要。很多App,正是因為有了動畫,所以才會覺得炫酷。移動端的動畫庫有非常的多,例如iOS上的Pop、web端的animate.css、Androi

Android 動畫)幀動畫動畫

1.Frame Animation(幀動畫) 幀動畫就是把多張圖片在定義的短時間內完成順序播放,最終呈現在視覺上的動態效果;幀動畫首先得具有圖片資源。 下面是幀動畫在Android開發中的具體實現: (1)activity_main.xml檔案: <

java io:File

File 類:檔案和目錄路徑名的抽象表示。 注意:File 類只能操作檔案的屬性,檔案的內容是不能操作的。   1、File 類的欄位     我們知道,各個平臺之間的路徑分隔符是不一樣的。   ①、對於UNIX平臺,絕對路徑名的字首始終為"/" 。

Android動畫解析()-----逐幀動畫動畫

今天專案又用到了動畫,發現之前掌握的那些又遺忘了不少,趁著有時間,再重新捋順一邊。 Android中的動畫分為 逐幀動畫,補間動畫,屬性動畫 三種. 逐幀動畫(Frame Animation) 逐幀動畫:就像GIF圖片一樣,通過一系列的Drawab

2016 Android 動畫 乾貨(

本系列文章會借鑑一些前輩的經典帖子。這裡對這些巨人表示感謝。 在最後我會放出一些根據這些動畫實現的小遊戲,以及原碼,不足的地方歡迎切磋。 Android的動畫一開始分為兩種方式實現 第一種就是:逐幀動畫 實現原理很簡單就是將一個完整的動畫拆分成一張張單獨的

Animation 動畫)——alpha、scale、translate、rotate、set的xml屬性及用法

Android的animation由四種類型組成:alpha、scale、translate、rotate,對應android官方文件地址:《Animation Resources》 1、XML配置檔案中 alpha 漸變透明度動畫效果 scale 漸變尺

Canny邊緣檢測算法原理及其VC實現()

常用 差分 實現圖 還需要 鏈接 傳感器 出了 關系 位置 轉自:http://blog.csdn.net/likezhaobin/article/details/6892176 圖象的邊緣是指圖象局部區域亮度變化顯著的部分,該區域的灰度剖面一般可以看作是一個階躍,既從

Java線程()

線程 thread runnable 程序、進程、線程的概念 程序(program):是為完成特定任務、用某種語言編寫的一組指令的集合。即指一段靜態的代碼,靜態對象。 進程(process):是程序的一次執行過程,或是正在運行的一個程序。動態過程:有它自身的產生、存在和消亡的過程。 如

css3動畫

gin char ng- pack mar ber 正在 one title 一.Keyframes介紹: Keyframes被稱為關鍵幀,[email protected]/* */rames”開頭,後面緊跟著是動畫名稱加上一對花括號“{…}”,括號中就是一些

View 動畫

坐標 開啟 cal art mage image 旋轉 true 動畫效果 補間動畫 先使用ImageView顯示一張圖片 ImageView iv=(ImageView)findViewById(R.id.iv); 1.透明 AlphaAnimation aa=new A

Java反射機制

java 反射 反射機制 工廠模式 1反射機制是什麽反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。在面向對象的世界裏,萬事萬物皆對象.在ja

WebSocket安卓客戶端實現()–連接建立與重連

ask 應該 header oid mha 主動推送 未收到 compile tde http://blog.csdn.net/zly921112/article/details/72973054 前言 這裏特別說明下因為WebSocket服務端是公司線上項目所以這裏ur