Android 動畫之View動畫

簡介

Android動畫主要有三種類型:View動畫、幀動畫和屬性動畫。其中,幀動畫也是View動畫的一種,它通過順序播放一系列圖像而產生動畫效果,只不過它和一般的平移、旋轉等View動畫在表現形式上略有不同。而屬性動畫是API11的新特性,在Android 3.0以下版本的手機中無法使用。下面主要介紹View動畫。
View動畫是一種作用于View對象的動畫,它支持4種動畫效果,分別為平移(translate)、旋轉(rotate)、縮放(scale)和透明度(alpha)。這四種動畫分別對應于Android中的TranslateAnimation、RotateAnimation、ScaleAnimation和AlphaAnimation這四個類。這幾種動畫均可以通過XML格式定義或通過Java代碼動態創建。

實現原理

每次繪制視圖時,View所在的ViewGroup中的drawChild函數會獲取該view的Animation的Transformation值,然后調用canvas.concat(transformToApply.getMatrix())函數,通過內部的矩陣運算完成動畫幀。如果動畫沒有完成,就繼續調用invalidate()函數,啟動下次繪制來驅動動畫,從而完成整個動畫的繪制。由此可見,View動畫其實是一個矩陣運算的過程。

優缺點

優勢:使用簡單,兼容性好

缺陷:

  1. 不具備交互性,View動畫作用的實際上是View的影像,而非真正改變了View的屬性狀態。也就是說,View動畫結束后,即便使用setFillAfter(true)使得view保持在動畫結束時的位置,view的真實位置依舊未發生變化,仍然處于最開始定義時的位置。因此,當view動畫結束后,其響應位置仍然位于動畫開始前的位置,這就使得其不具備交互性;
  2. View動畫只能作用于View對象,且提供的動畫種類有限;

View動畫的使用

通過Java代碼動態創建動畫

步驟:
  1. 創建TranslateAnimation、RotateAnimation、ScaleAnimation或AlphaAnimation對象;
  2. 設置創建的動畫對象的屬性,如動畫執行時間、延遲時間、起始位置、結束位置等;
  3. 通過View.startAnimation()方法開啟動畫;
    注:可以通過Animation.setAnimationListener()設置動畫的監聽器,監聽動畫的開始、結束和重復狀態,并在必要的時候添加自己的操作;
示例:
  • 平移動畫:
TranslateAnimation translate = new TranslateAnimation(0, 120, 0, 100);
translate.setFillAfter(true);
translate.setDuration(1000);
image.startAnimation(translate);
  • 旋轉動畫:

final RotateAnimation rotate1 = new RotateAnimation(0, 360); // 圍繞自己的左上角向右旋轉360度
final RotateAnimation rotate2 = new RotateAnimation(0, 90, Animation.RELATIVE_TO_PARENT, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f); // X軸坐標向右偏移0.5倍父控件寬度,Y軸坐標向下偏移0.5倍自身寬度,然后圍繞該點向右旋轉90度
rotate1.setDuration(1000); //設置動畫時長
// 設置動畫事件監聽器
rotate1.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(mContext, "Start rotate", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(mContext, "End rotate", Toast.LENGTH_SHORT).show();
rotate2.setDuration(1000);
image.startAnimation(rotate2);
}
@Override
public void onAnimationRepeat(Animation animation) {
Toast.makeText(mContext, "Repeat rotate", Toast.LENGTH_SHORT).show();
}});
image.startAnimation(mAnimation); // 開始動畫

+ 縮放動畫:
```Java
ScaleAnimation scale = new ScaleAnimation(1, 1.5f, 1, 1.5f, Animation.RELATIVE_TO_PARENT, 0.5f, 
Animation.RELATIVE_TO_SELF, 0.5f);
scale.setFillAfter(true);
scale.setDuration(1000);
image.startAnimation(scale);
  • 透明度動畫:

AlphaAnimation alpha = new AlphaAnimation(1, 0);
alpha.setDuration(1000);
alpha.setRepeatMode(Animation.REVERSE); //設置重復模式
alpha.setRepeatCount(5); //設置重復次數
image.startAnimation(alpha);

+ 動畫集:
```Java
AnimationSet as = new AnimationSet(true);   // 動畫集共享插值器
as.setDuration(3000);AlphaAnimation aa = new AlphaAnimation(0. 1);
aa.setDuration(1000);
as.addAnimation(aa);
TranslateAnimation ta = new TranslateAnimation(0, 100, 0, 100);
ta.setDuration(1000);
as.addAnimation(ta);
image.startAnimation(as);
屬性解析:
  • 動畫的原點默認為控件自身的左上角,向右為X軸正向,向下為Y軸正向
動畫坐標系
  • 動畫常見共有屬性:
  • setInterpolator(Interpolator i):設置動畫插值器(后面解釋),即設置動畫的加速模式,默認為線性插值器(勻速變化),還可以設置為AccelerateDecelerateInterpolator、AccelerateInterpolator等,或者自定義
  • setFillAfter(boolean fillAfter): 動畫結束后是否保持在結束狀態,true表示保持在結束時的狀態,false表示返回開始前的狀態
  • setFillBefore(boolean fillBefore):true表示動畫結束時,畫面停留在第一幀
  • setDuration(long durationMillis):動畫持續時長,單位:毫秒
  • setRepeatCount(int repeatCount):動畫重復次數,-1表示無限循環
  • setRepeatMode(int repeatMode):動畫重復模式,為RESTART或REVERSE
  • setStartTime(long startTimeMillis):動畫開始時間,以毫秒表示
  • setStartOffset(long startOffset):動畫延遲時長,即延遲startOffset毫秒開始動畫,當startOffset>0時,動畫開始時間為startTimeMillis+startOffset
  • setZAdjustment(int zAdjustment):動畫過程中Z軸方向的模式,默認為normal
  • 平移動畫屬性:
public TranslateAnimation(Context context, AttributeSet attrs);
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, 
float toYDelta);
public TranslateAnimation(int fromXType, float fromXValue, int toXType, 
float toXValue, int fromYType, float fromYValue, int toYType, float toYValue);

如上為TranslateAnimation的三個構造方法,最終均為了設置第三個構造方法中的幾個參數所對應的TranslateAnimation屬性值,所以下面分別介紹這些屬性的含義。

  • fromXTypefromXValue:這倆屬性分別表示平移起點X軸方向的偏移類型和偏移量,fromXType有三種取值可選,分別為Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF 和 Animation.RELATIVE_TO_PARENT
    fromXType取值為Animation.ABSOLUTE時,表示X軸方向的平移起點絕對平移fromXValue個像素點,此時fromXValue為一個絕對像素值;
    fromXType取值為Animation.RELATIVE_TO_SELF時,表示X軸方向的平移起點相對自身平移fromXValue **** 控件寬度個像素點,此時fromXValue為一個百分比值,表示偏移量相對控件自身寬度的百分比;
    fromXType取值為Animation.RELATIVE_TO_PARENT 時,表示X軸方向的平移起點相對父控件平移
    fromXValue **** 父控件寬度個像素點,此時fromXValue為一個百分比值,表示偏移量相對父控件寬度的百分比;

  • fromYTypefromYValue:分別表示平移起點Y軸方向的偏移類型和偏移量,具體含義同fromXType 和 fromXValue;

  • toXType 和 toXValue、toYType 和 toYValue:則表示終點位置的偏移量,具體含義同起點偏移量;

  • 旋轉動畫屬性:

public RotateAnimation(Context context, AttributeSet attrs)
public RotateAnimation(float fromDegrees, float toDegrees)
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, 
int pivotYType, float pivotYValue)

如上為RotateAnimation的四個構造方法,其目的均為了設置fromDegrees、toDegrees、pivotXType、pivotXValue、pivotYType、pivotYValue這幾個屬性值,下面對這幾個屬性分別進行介紹。

  • fromDegreestoDegrees:這兩個屬性分別表示旋轉起始角度和終止角度;

  • pivotXType、pivotXValue、pivotYType、pivotYValue:這四個屬性用于設置旋轉中心點位置。
    pivotXType 和 pivotXValue分別表示旋轉中心在X軸方向相對原點(即控件左上角)的偏移類型和偏移量,pivotXType有三個可選取值:Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF 和 Animation.RELATIVE_TO_PARENT,分別表示絕對偏移、相對自身偏移和相對父控件偏移,當取Animation.ABSOLUTE時,pivotXValue是一個絕對數值,否則pivotXValue是一個相對數值(取值為1表示100%)。
    pivotYType 和 pivotYValue:分別表示旋轉中心在Y軸方向相對原點的偏移類型和偏移量,具體含義同pivotXType 和 pivotXValue。

    示例使用如下:

final RotateAnimation rotate2 = new RotateAnimation(0, 90, Animation.RELATIVE_TO_PARENT, 0.5f,      
Animation.RELATIVE_TO_SELF, 0.5f); 
// X軸坐標向右偏移0.5倍父控件寬度,Y軸坐標向下偏移0.5倍自身寬度,然后圍繞該點向右旋轉90度
  • 縮放動畫屬性:
public ScaleAnimation(Context context, AttributeSet attrs)
public ScaleAnimation(float fromX, float toX, float fromY, float toY)
public ScaleAnimation(float fromX, float toX, float fromY, float toY, 
float pivotX, float pivotY)
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)  

如上為ScaleAnimation的四個構造函數,最終均為了設置ScaleAnimation的如下幾個屬性:
fromX、toX、fromY、 toY、pivotXType、pivotXValue、pivotYType 和 pivotYValue。

  • fromXtoX:這兩個屬性分別表示水平方向上相對自身的起始縮放因子和終止縮放因子,1表示100%,即原始大小,因此水平方向縮放的總長度為(toX-fromX) * width

  • fromYtoY:這兩個屬性分別表示垂直方向上相對自身的起始縮放因子和終止縮放因子

  • pivotXType、pivotXValue、pivotYType 和 pivotYValue:這四個屬性用于控制縮放中心坐標點位置。具體含義參見旋轉動畫屬性說明部分。

    示例使用如下:

ScaleAnimation scale = new ScaleAnimation(1, 1.5f, 1, 1.5f, Animation.RELATIVE_TO_PARENT, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
// 表示以X坐標向右偏移0.5倍父控件寬度,Y坐標向下偏移0.5倍自身高度的點為縮放中心點
// 將控件的水平和垂直方向分別從當前寬高放大0.5倍
```

  • 透明度動畫屬性:
public AlphaAnimation(Context context, AttributeSet attrs)
public AlphaAnimation(float fromAlpha, float toAlpha)

如上為AlphaAnimation的兩個構造方法,主要看第二個構造方法中的兩個屬性fromAlpha 和 toAlpha,這兩個屬性分別表示動畫開始時的透明度和結束時的透明度,0.0表示完全透明,即不可見,1.0表示完全不透明。

示例使用如下:

AlphaAnimation alpha = new AlphaAnimation(1, 0);
// 表示將控件從不透明狀態調整到完全透明狀態
  • 動畫集(AnimationSet)屬性:
    動畫集用于將一組一起播放的動畫組合為一個動畫。動畫集從父類Animation中繼承的一些屬性的作用方式需要認真加以理解,因為不同屬性的表現方式各異,有些屬性只作用于動畫集自身,有些屬性會作用于動畫集中的子動畫,而有些屬性又會被忽略。
    • duration, repeatMode, fillBefore, fillAfter: 當為AnimationSet設置了這幾個屬性的時候,這幾個屬性將會作用于該動畫集中的所有子動畫中
    • repeatCount, fillEnabled: 這兩個屬性在AnimationSet中不起作用,將會被忽略;
    • startOffset, shareInterpolator: 這兩個屬性將作用于AnimationSet自身

插值器

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,202評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,742評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,580評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,297評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,688評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,875評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,438評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,183評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,384評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,612評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,022評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,297評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,093評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,330評論 2 377

推薦閱讀更多精彩內容

  • 1 背景 不能只分析源碼呀,分析的同時也要整理歸納基礎知識,剛好有人微博私信讓全面說說Android的動畫,所以今...
    未聞椛洺閱讀 2,735評論 0 10
  • Animation Animation類是所有動畫(scale、alpha、translate、rotate)的基...
    四月一號閱讀 1,933評論 0 10
  • 首先附上谷歌官方文檔鏈接地址 一、幀動畫(Frame animation) 先來看看谷歌的官方定義:An anim...
    Geeks_Liu閱讀 2,102評論 1 3
  • 作業一:五個《琉璃瓦》中的比喻 1..霜濃月薄的銀藍的夜里,惟有一兩家店鋪點著強烈的電燈,晶亮 的玻璃窗里品字式堆...
    那冬閱讀 266評論 2 0
  • 1、關閉客戶端和服務端的UAC 系統 =》安全和維護 =》更改用戶賬戶控制設置 =》從不通知 2、重啟服務端和客戶...
    南波閱讀 3,736評論 0 0