Android 三種動畫介紹

本文是轉(zhuǎn)載其它同行的結(jié)果,這里做個記錄事镣,防止需要的時候找不到步鉴,文末已標(biāo)注轉(zhuǎn)載源地址。

1 背景

不能只分析源碼呀璃哟,分析的同時也要整理歸納基礎(chǔ)知識氛琢,剛好有人微博私信讓全面說說Android的動畫,所以今天來一發(fā)Android應(yīng)用的各種Animation大集合随闪。英文厲害的請直接移步參考Android Developer阳似。

Android系統(tǒng)提供了很多豐富的API去實現(xiàn)UI的2D與3D動畫,最主要的劃分可以分為如下幾類:

  • View Animation: 視圖動畫在古老的Android版本系統(tǒng)中就已經(jīng)提供了铐伴,只能被用來設(shè)置View的動畫撮奏。

  • Drawable Animation: 這種動畫(也叫Frame動畫、幀動畫)其實可以劃分到視圖動畫的類別当宴,專門用來一個一個的顯示Drawable的resources畜吊,就像放幻燈片一樣。

  • Property Animation: 屬性動畫只對Android 3.0(API 11)以上版本的Android系統(tǒng)才有效户矢,這種動畫可以設(shè)置給任何Object玲献,包括那些還沒有渲染到屏幕上的對象。這種動畫是可擴(kuò)展的梯浪,可以讓你自定義任何類型和屬性的動畫捌年。

可以看見,當(dāng)前應(yīng)用程序開發(fā)涉及的主要動畫也就這三大類驱证,我們接下來以類別為基礎(chǔ)來慢慢展開說明延窜。

2 View Animation(視圖動畫)使用詳解

android:duration 動畫持續(xù)時間恋腕,以毫秒為單位
android:fillAfter 如果設(shè)置為true抹锄,控件動畫結(jié)束時,將保持動畫最后時的狀態(tài)
android:fillBefore 如果設(shè)置為true,控件動畫結(jié)束時,還原到開始動畫前的狀態(tài)
android:fillEnabled 與android:fillBefore 效果相同伙单,都是在動畫結(jié)束時获高,將控件還原到初始化狀態(tài)
android:repeatCount 重復(fù)次數(shù)
android:repeatMode 重復(fù)類型,有reverse和restart兩個值吻育,reverse表示倒序回放念秧,restart表示重新放一遍,必須與repeatCount一起使用才能看到效果布疼。因為這里的意義是重復(fù)的類型摊趾,即回放時的動作。
android:interpolator 設(shè)定插值器游两,其實就是指定的動作效果砾层,比如彈跳效果等,不在這小節(jié)中講解贱案,后面會單獨列出一單講解肛炮。

2-1 視圖動畫概述

視圖動畫,也叫Tween(補(bǔ)間)動畫可以在一個視圖容器內(nèi)執(zhí)行一系列簡單變換(位置宝踪、大小侨糟、旋轉(zhuǎn)、透明度)瘩燥。譬如秕重,如果你有一個TextView對象,您可以移動厉膀、旋轉(zhuǎn)悲幅、縮放、透明度設(shè)置其文本站蝠,當(dāng)然汰具,如果它有一個背景圖像,背景圖像會隨著文本變化菱魔。

補(bǔ)間動畫通過XML或Android代碼定義留荔,建議使用XML文件定義,因為它更具可讀性澜倦、可重用性聚蝶。

如下是視圖動畫相關(guān)的類繼承關(guān)系:

[圖片上傳失敗...(image-ede1bd-1628735635565)]

java類名 xml關(guān)鍵字 描述信息
AlphaAnimation <alpha> 放置在res/anim/目錄下 漸變透明度動畫效果
RotateAnimation <rotate> 放置在res/anim/目錄下 畫面轉(zhuǎn)移旋轉(zhuǎn)動畫效果
ScaleAnimation <scale> 放置在res/anim/目錄下 漸變尺寸伸縮動畫效果
TranslateAnimation <translate> 放置在res/anim/目錄下 畫面轉(zhuǎn)換位置移動動畫效果
AnimationSet <set> 放置在res/anim/目錄下 一個持有其它動畫元素alpha、scale藻治、translate碘勉、rotate或者其它set元素的容器

通過上圖和上表可以直觀的看出來補(bǔ)間動畫的關(guān)系及種類了吧,接下來我們就詳細(xì)一個一個的介紹一下各種補(bǔ)間動畫桩卵。

2-2 視圖動畫詳細(xì)說明

可以看出來Animation抽象類是所有補(bǔ)間動畫類的基類验靡,所以基類會提供一些通用的動畫屬性方法倍宾,如下我們就來詳細(xì)看看這些屬性,關(guān)于這些屬性詳細(xì)官方解釋FQ點擊我或者FQ點擊我胜嗓。

2-2-1 Animation屬性詳解

xml屬性 java方法 解釋
android:detachWallpaper setDetachWallpaper(boolean) 是否在壁紙上運行
android:duration setDuration(long) 動畫持續(xù)時間高职,毫秒為單位
android:fillAfter setFillAfter(boolean) 控件動畫結(jié)束時是否保持動畫最后的狀態(tài)
android:fillBefore setFillBefore(boolean) 控件動畫結(jié)束時是否還原到開始動畫前的狀態(tài)
android:fillEnabled setFillEnabled(boolean) 與android:fillBefore效果相同
android:interpolator setInterpolator(Interpolator) 設(shè)定插值器(指定的動畫效果,譬如回彈等)
android:repeatCount setRepeatCount(int) 重復(fù)次數(shù)
android:repeatMode setRepeatMode(int) 重復(fù)類型有兩個值辞州,reverse表示倒序回放怔锌,restart表示從頭播放
android:startOffset setStartOffset(long) 調(diào)用start函數(shù)之后等待開始運行的時間,單位為毫秒
android:zAdjustment setZAdjustment(int) 表示被設(shè)置動畫的內(nèi)容運行時在Z軸上的位置(top/bottom/normal)变过,默認(rèn)為normal

也就是說埃元,無論我們補(bǔ)間動畫的哪一種都已經(jīng)具備了這種屬性,也都可以設(shè)置使用這些屬性中的一個或多個媚狰。

那接下來我們就看看每種補(bǔ)間動畫特有的一些屬性說明吧亚情。

2-2-2 Alpha屬性詳解

xml屬性 java方法 解釋
android:fromAlpha AlphaAnimation(float fromAlpha, …) 動畫開始的透明度(0.0到1.0,0.0是全透明哈雏,1.0是不透明)
android:toAlpha AlphaAnimation(…, float toAlpha) 動畫結(jié)束的透明度楞件,同上

2-2-3 Rotate屬性詳解

xml屬性 java方法 解釋
android:fromDegrees RotateAnimation(float fromDegrees, …) 旋轉(zhuǎn)開始角度,正代表順時針度數(shù)裳瘪,負(fù)代表逆時針度數(shù)
android:toDegrees RotateAnimation(…, float toDegrees, …) 旋轉(zhuǎn)結(jié)束角度土浸,正代表順時針度數(shù),負(fù)代表逆時針度數(shù)
android:pivotX RotateAnimation(…, float pivotX, …) 縮放起點X坐標(biāo)(數(shù)值彭羹、百分?jǐn)?shù)黄伊、百分?jǐn)?shù)p,譬如50表示以當(dāng)前View左上角坐標(biāo)加50px為初始點派殷、50%表示以當(dāng)前View的左上角加上當(dāng)前View寬高的50%做為初始點还最、50%p表示以當(dāng)前View的左上角加上父控件寬高的50%做為初始點)
android:pivotY RotateAnimation(…, float pivotY) 縮放起點Y坐標(biāo),同上規(guī)律

2-2-4 Scale屬性詳解

xml屬性 java方法 解釋
android:fromXScale ScaleAnimation(float fromX, …) 初始X軸縮放比例毡惜,1.0表示無變化
android:toXScale ScaleAnimation(…, float toX, …) 結(jié)束X軸縮放比例
android:fromYScale ScaleAnimation(…, float fromY, …) 初始Y軸縮放比例
android:toYScale ScaleAnimation(…, float toY, …) 結(jié)束Y軸縮放比例
android:pivotX ScaleAnimation(…, float pivotX, …) 縮放起點X軸坐標(biāo)(數(shù)值拓轻、百分?jǐn)?shù)、百分?jǐn)?shù)p经伙,譬如50表示以當(dāng)前View左上角坐標(biāo)加50px為初始點扶叉、50%表示以當(dāng)前View的左上角加上當(dāng)前View寬高的50%做為初始點、50%p表示以當(dāng)前View的左上角加上父控件寬高的50%做為初始點)
android:pivotY ScaleAnimation(…, float pivotY) 縮放起點Y軸坐標(biāo)帕膜,同上規(guī)律

2-2-5 Translate屬性詳解

xml屬性 java方法 解釋
android:fromXDelta TranslateAnimation(float fromXDelta, …) 起始點X軸坐標(biāo)(數(shù)值枣氧、百分?jǐn)?shù)、百分?jǐn)?shù)p垮刹,譬如50表示以當(dāng)前View左上角坐標(biāo)加50px為初始點达吞、50%表示以當(dāng)前View的左上角加上當(dāng)前View寬高的50%做為初始點、50%p表示以當(dāng)前View的左上角加上父控件寬高的50%做為初始點)
android:fromYDelta TranslateAnimation(…, float fromYDelta, …) 起始點Y軸從標(biāo)荒典,同上規(guī)律
android:toXDelta TranslateAnimation(…, float toXDelta, …) 結(jié)束點X軸坐標(biāo)酪劫,同上規(guī)律
android:toYDelta TranslateAnimation(…, float toYDelta) 結(jié)束點Y軸坐標(biāo)吞鸭,同上規(guī)律

2-2-6 AnimationSet詳解

AnimationSet繼承自Animation,是上面四種的組合容器管理類契耿,沒有自己特有的屬性,他的屬性繼承自Animation螃征,所以特別注意搪桂,當(dāng)我們對set標(biāo)簽使用Animation的屬性時會對該標(biāo)簽下的所有子控件都產(chǎn)生影響。

2-3 視圖動畫使用方法

通過上面對于動畫的屬性介紹之后我們來看看在Android中這些動畫如何使用(PS:這里直接演示xml方式盯滚,至于Java方式太簡單了就不說了)踢械,如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:shareInterpolator=["true" | "false"] >
    <alpha
        android:fromAlpha="float"
        android:toAlpha="float" />
    <scale
        android:fromXScale="float"
        android:toXScale="float"
        android:fromYScale="float"
        android:toYScale="float"
        android:pivotX="float"
        android:pivotY="float" />
    <translate
        android:fromXDelta="float"
        android:toXDelta="float"
        android:fromYDelta="float"
        android:toYDelta="float" />
    <rotate
        android:fromDegrees="float"
        android:toDegrees="float"
        android:pivotX="float"
        android:pivotY="float" />
    <set>
        ...
    </set>
</set>
ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);

上面就是一個標(biāo)準(zhǔn)的使用我們定義的補(bǔ)間動畫的模板。至于補(bǔ)間動畫的使用魄藕,Animation還有如下一些比較實用的方法介紹:

Animation類的方法 解釋
reset() 重置Animation的初始化
cancel() 取消Animation動畫
start() 開始Animation動畫
setAnimationListener(AnimationListener listener) 給當(dāng)前Animation設(shè)置動畫監(jiān)聽
hasStarted() 判斷當(dāng)前Animation是否開始
hasEnded() 判斷當(dāng)前Animation是否結(jié)束

既然補(bǔ)間動畫只能給View使用内列,那就來看看View中和動畫相關(guān)的幾個常用方法吧,如下:

View類的常用動畫操作方法 解釋
startAnimation(Animation animation) 對當(dāng)前View開始設(shè)置的Animation動畫
clearAnimation() 取消當(dāng)View在執(zhí)行的Animation動畫

到此整個Android的補(bǔ)間動畫常用詳細(xì)屬性及方法全部介紹完畢背率,如有特殊的屬性需求可以訪問Android Developer查閱即可话瞧。如下我們就來個綜合大演練。

2-4 視圖動畫注意事項

關(guān)于視圖動畫(補(bǔ)間動畫)的例子我就不介紹了寝姿,網(wǎng)上簡直多的都泛濫了交排。只是強(qiáng)調(diào)在使用補(bǔ)間動畫時注意如下一點即可:

特別特別注意:補(bǔ)間動畫執(zhí)行之后并未改變View的真實布局屬性值。切記這一點饵筑,譬如我們在Activity中有一個 Button在屏幕上方埃篓,我們設(shè)置了平移動畫移動到屏幕下方然后保持動畫最后執(zhí)行狀態(tài)呆在屏幕下方,這時如果點擊屏幕下方動畫執(zhí)行之后的Button是沒 有任何反應(yīng)的根资,而點擊原來屏幕上方?jīng)]有Button的地方卻響應(yīng)的是點擊Button的事件架专。

2-5 視圖動畫Interpolator插值器詳解

2-5-1 插值器簡介

介紹補(bǔ)間動畫插值器之前我們先來看一幅圖,如下:

[圖片上傳失敗...(image-53a02a-1628735635565)]

可以看見其實各種插值器都是實現(xiàn)了Interpolator接口而已玄帕,同時可以看見系統(tǒng)提供了許多已經(jīng)實現(xiàn)OK的插值器部脚,具體如下:

java類 xml id值 描述
AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 動畫始末速率較慢,中間加速
AccelerateInterpolator @android:anim/accelerate_interpolator 動畫開始速率較慢裤纹,之后慢慢加速
AnticipateInterpolator @android:anim/anticipate_interpolator 開始的時候從后向前甩
AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 類似上面AnticipateInterpolator
BounceInterpolator @android:anim/bounce_interpolator 動畫結(jié)束時彈起
CycleInterpolator @android:anim/cycle_interpolator 循環(huán)播放速率改變?yōu)檎仪€
DecelerateInterpolator @android:anim/decelerate_interpolator 動畫開始快然后慢
LinearInterpolator @android:anim/linear_interpolator 動畫勻速改變
OvershootInterpolator @android:anim/overshoot_interpolator 向前彈出一定值之后回到原來位置
PathInterpolator 新增睛低,定義路徑坐標(biāo)后按照路徑坐標(biāo)來跑。

如上就是系統(tǒng)提供的一些插值器服傍,下面我們來看看怎么使用他們钱雷。

2-5-2 插值器使用方法

插值器的使用比較簡答,如下:

<set android:interpolator="@android:anim/accelerate_interpolator">
    ...
</set>

2-5-3 插值器的自定義

有時候你會發(fā)現(xiàn)系統(tǒng)提供的插值器不夠用吹零,可能就像View一樣需要自定義罩抗。所以接下來我們來看看插值器的自定義,關(guān)于插值器的自定義分為兩種實現(xiàn)方式灿椅,xml自定義實現(xiàn)(其實就是對現(xiàn)有的插值器的一些屬性修改)或者java代碼實現(xiàn)方式套蒂。如下我們來說說钞支。

先看看XML自定義插值器的步驟:

  • 在res/anim/目錄下創(chuàng)建filename.xml文件。
  • 修改你準(zhǔn)備自定義的插值器如下:
<?xml version="1.0" encoding="utf-8"?>
<InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android"
    android:attribute_name="value"
    />
  • 在你的補(bǔ)間動畫文件中引用該文件即可操刀。

可以看見上面第二步修改的是現(xiàn)有插值器的一些屬性烁挟,但是有些插值器卻不具備修改屬性,具體如下:

<accelerateDecelerateInterpolator>

無可自定義的attribute骨坑。

<accelerateInterpolator>

android:factor 浮點值撼嗓,加速速率(默認(rèn)值為1)。

<anticipateInterploator>

android:tension 浮點值欢唾,起始點后拉的張力數(shù)(默認(rèn)值為2)且警。

<anticipateOvershootInterpolator>

android:tension 浮點值,起始點后拉的張力數(shù)(默認(rèn)值為2)礁遣。
android:extraTension 浮點值斑芜,拉力的倍數(shù)(默認(rèn)值為1.5)。

<bounceInterpolator>

無可自定義的attribute祟霍。

<cycleInterplolator>

android:cycles 整形杏头,循環(huán)的個數(shù)(默認(rèn)為1)。

<decelerateInterpolator>

android:factor 浮點值沸呐,減速的速率(默認(rèn)為1)大州。

<linearInterpolator>

無可自定義的attribute。

<overshootInterpolator>

android:tension 浮點值垂谢,超出終點后的張力(默認(rèn)為2)厦画。

再來看看Java自定義插值器的(Java自定義插值器其實是xml自定義的升級,也就是說如果我們修改xml的屬性還不能滿足需求滥朱,那就可以選擇通過Java來實現(xiàn))方式根暑。

可以看見上面所有的Interpolator都實現(xiàn)了Interpolator接口,而Interpolator接口又繼承自 TimeInterpolator徙邻,TimeInterpolator接口定義了一個float getInterpolation(float input);方法排嫌,這個方法是由系統(tǒng)調(diào)用的,其中的參數(shù)input代表動畫的時間缰犁,在0和1之間淳地,也就是開始和結(jié)束之間。

如下就是一個動畫始末速率較慢帅容、中間加速的AccelerateDecelerateInterpolator插值器:

public class AccelerateDecelerateInterpolator extends BaseInterpolator
        implements NativeInterpolatorFactory {
    ......
    public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }
    ......
}

到此整個補(bǔ)間動畫與補(bǔ)間動畫的插值器都分析完畢了颇象,接下來看下別的動畫。

3 Drawable Animation(Drawable動畫)使用詳解

3-1 Drawable動畫概述

Drawable動畫其實就是Frame動畫(幀動畫)并徘,它允許你實現(xiàn)像播放幻燈片一樣的效果遣钳,這種動畫的實質(zhì)其實是Drawable,所以這種動畫的XML定義方式文件一般放在res/drawable/目錄下麦乞。具體關(guān)于幀動畫的xml使用方式FQ點擊我查看蕴茴,java方式FQ點擊我查看劝评。

如下圖就是幀動畫的源碼文件:

[圖片上傳失敗...(image-af7f6-1628735635564)]

可以看見實際的真實父類就是Drawable。

3-2 Drawable動畫詳細(xì)說明

我們依舊可以使用xml或者java方式實現(xiàn)幀動畫倦淀。但是依舊推薦使用xml蒋畜,具體如下:

<animation-list> 必須是根節(jié)點,包含一個或者多個<item>元素撞叽,屬性有:

  • android:oneshot true代表只執(zhí)行一次姻成,false循環(huán)執(zhí)行。
  • <item> 類似一幀的動畫資源能扒。

<item> animation-list的子項佣渴,包含屬性如下:

  • android:drawable 一個frame的Drawable資源辫狼。
  • android:duration 一個frame顯示多長時間初斑。

3-3 Drawable動畫實例演示

關(guān)于幀動畫相對來說比較簡單,這里給出一個常規(guī)使用框架膨处,如下:

<!-- 注意:rocket.xml文件位于res/drawable/目錄下 -->
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot=["true" | "false"] >
    <item
        android:drawable="@[package:]drawable/drawable_resource_name"
        android:duration="integer" />
</animation-list>
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);

rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
rocketAnimation.start();

特別注意见秤,AnimationDrawable的start()方法不能在Activity的onCreate方法中調(diào)運,因為AnimationDrawable還未完全附著到window上真椿,所以最好的調(diào)運時機(jī)是onWindowFocusChanged()方法中鹃答。

至此幀動畫也就說明完成了。讓我們接下來進(jìn)入Android更牛叉的動畫類型突硝。

4 Property Animation(屬性動畫)使用詳解

在使用屬性動畫之前先來看幾個常用的View屬性成員:

  • translationX测摔,translationY:控制View的位置,值是相對于View容器左上角坐標(biāo)的偏移解恰。
  • rotationX锋八,rotationY:控制相對于軸心旋轉(zhuǎn)。
  • x护盈,y:控制View在容器中的位置,即左上角坐標(biāo)加上translationX和translationY的值。
  • alpha:控制View對象的alpha透明度值瘤缩。

這幾個常用的屬性相信大家都很熟悉伺糠,接下來的屬性動畫我們就從這里展開。

4-1 屬性動畫概述

Android 3.0以后引入了屬性動畫胸竞,屬性動畫可以輕而易舉的實現(xiàn)許多View動畫做不到的事欺嗤,上面也看見了,View動畫無非也就做那幾種事情卫枝,別的也搞不定剂府,而 屬性動畫就可以的,譬如3D旋轉(zhuǎn)一張圖片剃盾。其實說白了腺占,你記住一點就行淤袜,屬性動畫實現(xiàn)原理就是修改控件的屬性值實現(xiàn)的動畫。

具體先看下類關(guān)系:

/**
 * This is the superclass for classes which provide basic support for animations which can be
 * started, ended, and have <code>AnimatorListeners</code> added to them.
 */
public abstract class Animator implements Cloneable {
    ......
}

所有的屬性動畫的抽象基類就是他衰伯。我們看下他的實現(xiàn)子類:
[圖片上傳失敗...(image-4f9bdc-1628735635564)]

其實可以看見铡羡,屬性動畫的實現(xiàn)有7個類(PS,之所以類繼承關(guān)系列表會出來那么多是因為我下載了所有版本的SDK意鲸,你只用關(guān)注我紅點標(biāo)注的就行烦周,妹 的,ubuntu下圖片處理工具怎么都這么難用)怎顾,進(jìn)去粗略分析可以發(fā)現(xiàn)读慎,好幾個是hide的類,而其他可用的類繼承關(guān)系又如下:

java類名 xml關(guān)鍵字 描述信息
ValueAnimator <animator> 放置在res/animator/目錄下 在一個特定的時間里執(zhí)行一個動畫
TimeAnimator 不支持/點我查看原因 時序監(jiān)聽回調(diào)工具
ObjectAnimator <objectAnimator> 放置在res/animator/目錄下 一個對象的一個屬性動畫
AnimatorSet <set> 放置在res/animator/目錄下 動畫集合

所以可以看見槐雾,我們平時使用屬性動畫的重點就在于AnimatorSet夭委、ObjectAnimator、TimeAnimator募强、ValueAnimator株灸。所以接下來我們就來依次說說如何使用。

4-2 屬性動畫詳細(xì)說明

4-2-1 屬性動畫計算原理

參看Android官方文檔擎值,英文原版詳情點我查看慌烧!

Android屬性動畫(注意最低兼容版本,不過可以使用開源項目來替代低版本問題)提供了以下屬性:

  • Duration:動畫的持續(xù)時間鸠儿;
  • TimeInterpolation:定義動畫變化速率的接口屹蚊,所有插值器都必須實現(xiàn)此接口,如線性进每、非線性插值器汹粤;
  • TypeEvaluator:用于定義屬性值計算方式的接口,有int品追、float玄括、color類型,根據(jù)屬性的起始肉瓦、結(jié)束值和插值一起計算出當(dāng)前時間的屬性值遭京;
  • Animation sets:動畫集合,即可以同時對一個對象應(yīng)用多個動畫泞莉,這些動畫可以同時播放也可以對不同動畫設(shè)置不同的延遲哪雕;
  • Frame refreash delay:多少時間刷新一次,即每隔多少時間計算一次屬性值鲫趁,默認(rèn)為10ms斯嚎,最終刷新時間還受系統(tǒng)進(jìn)程調(diào)度與硬件的影響;
  • Repeat Country and behavoir:重復(fù)次數(shù)與方式,如播放3次堡僻、5次糠惫、無限循環(huán),可以讓此動畫一直重復(fù)钉疫,或播放完時向反向播放硼讽;

上面就是一個線性勻速動畫,描述了一個Object的X屬性運動動畫牲阁,該對象的X坐標(biāo)在40ms內(nèi)從0移動到40固阁,每10ms刷新一次,移動4次城菊,每次移動為40/4=10pixel备燃。

上面是一個非勻速動畫,描述了一個Object的X屬性運動動畫凌唬,該對象的X坐標(biāo)在40ms內(nèi)從0移動到40并齐,每10ms刷新一次,移動4次法瑟,但是速率不同冀膝,開始和結(jié)束的速度要比中間部分慢唁奢,即先加速后減速霎挟。

接下來我們來詳細(xì)的看一下,屬性動畫系統(tǒng)的重要組成部分是如何計算動畫值的麻掸,下圖描述了如上面所示動畫的實現(xiàn)作用過程酥夭。

其中的ValueAnimator是動畫的執(zhí)行類,跟蹤了當(dāng)前動畫的執(zhí)行時間和當(dāng)前時間下的屬性值脊奋;ValueAnimator封裝了動畫的 TimeInterpolator時間插值器和一個TypeEvaluator類型估值熬北,用于設(shè)置動畫屬性的值,就像上面圖2非線性動畫 里诚隙,TimeInterpolator使用了AccelerateDecelerateInterpolator讶隐、TypeEvaluator使用了 IntEvaluator。

為了執(zhí)行一個動畫久又,你需要創(chuàng)建一個ValueAnimator巫延,并且指定目標(biāo)對象屬性的開始、結(jié)束值和持續(xù)時間地消。在調(diào)用start后炉峰,整個動畫過程 中, ValueAnimator會根據(jù)已經(jīng)完成的動畫時間計算得到一個0到1之間的分?jǐn)?shù)脉执,代表該動畫的已完成動畫百分比疼阔。0表示0%,1表示100%,譬如上 面圖一線性勻速動畫中總時間 t = 40 ms婆廊,t = 10 ms的時候是 0.25迅细。

當(dāng)ValueAnimator計算完已完成動畫分?jǐn)?shù)后,它會調(diào)用當(dāng)前設(shè)置的TimeInterpolator淘邻,去計算得到一個 interpolated(插值)分?jǐn)?shù)疯攒,在計算過程中,已完成動畫百分比會被加入到新的插值計算中列荔。如上圖2非線性動畫中敬尺,因為動畫的運動是緩慢加速的, 它的插值分?jǐn)?shù)大約是 0.15贴浙,小于t = 10ms時的已完成動畫分?jǐn)?shù)0.25砂吞。而在上圖1中,這個插值分?jǐn)?shù)一直和已完成動畫分?jǐn)?shù)是相同的崎溃。

當(dāng)插值分?jǐn)?shù)計算完成后蜻直,ValueAnimator會根據(jù)插值分?jǐn)?shù)調(diào)用合適的 TypeEvaluator去計算運動中的屬性值。

好了袁串,現(xiàn)在我們來看下代碼就明白這段話了概而,上面圖2非線性動畫里,TimeInterpolator使用了 AccelerateDecelerateInterpolator囱修、TypeEvaluator使用了IntEvaluator赎瑰。所以這些類都是標(biāo)準(zhǔn)的 API,我們來看下標(biāo)準(zhǔn)API就能類比自己寫了破镰,如下:

首先計算已完成動畫時間分?jǐn)?shù)(以10ms為例):t=10ms/40ms=0.25餐曼。

接著看如下源碼如何實現(xiàn)計算差值分?jǐn)?shù)的:

public class AccelerateDecelerateInterpolator extends BaseInterpolator
        implements NativeInterpolatorFactory {
    public AccelerateDecelerateInterpolator() {
    }
    ......
    //這是我們關(guān)注重點,可以發(fā)現(xiàn)如下計算公式計算后(input即為時間因子)插值大約為0.15鲜漩。
    public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }
    ......
}

其實AccelerateDecelerateInterpolator的基類接口就是TimeInterpolator源譬,如下,他只有g(shù)etInterpolation方法孕似,也就是上面我們關(guān)注的方法踩娘。

public interface TimeInterpolator {
    float getInterpolation(float input);
}

接著ValueAnimator會根據(jù)插值分?jǐn)?shù)調(diào)用合適的TypeEvaluator(IntEvaluator)去計算運動中的屬性值,如下喉祭,因為startValue = 0养渴,所以屬性值:0+0.15*(40-0)= 6。

public class IntEvaluator implements TypeEvaluator<Integer> {
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
        int startInt = startValue;
        return (int)(startInt + fraction * (endValue - startInt));
    }
}

這就是官方給的一個關(guān)于屬性動畫實現(xiàn)的過程及基本原理解釋臂拓,相信你看到這里是會有些迷糊的厚脉,沒關(guān)系,你先有個大致概念就行胶惰,接下來我們會慢慢進(jìn)入實戰(zhàn)傻工,因為Android的屬性動畫相對于其他動畫來說涉及的知識點本來就比較復(fù)雜,所以我們慢慢來。

4-2-2 XML方式屬性動畫

在xml中可直接用的屬性動畫節(jié)點有ValueAnimator中捆、ObjectAnimator鸯匹、AnimatorSet。如下是官方的一個例子和解釋(詳情點我):

<set
  android:ordering=["together" | "sequentially"]>

    <objectAnimator
        android:propertyName="string"
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>

    <animator
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>

    <set>
        ...
    </set>
</set>

<set>屬性解釋:

xml屬性 解釋
android:ordering 控制子動畫啟動方式是先后有序的還是同時進(jìn)行泄伪。sequentially:動畫按照先后順序殴蓬;together(默認(rèn)):動畫同時啟動;

<objectAnimator>屬性解釋:

xml屬性 解釋
android:propertyName String類型蟋滴,必須要設(shè)置的節(jié)點屬性染厅,代表要執(zhí)行動畫的屬性(通過名字引用),辟如你可以指定了一個View的”alpha” 或者 “backgroundColor” 津函,這個objectAnimator元素沒有對外說明target屬性肖粮,所以你不能在XML中設(shè)置執(zhí)行這個動畫,必須通過調(diào)用 loadAnimator()方法加載你的XML動畫資源尔苦,然后調(diào)用setTarget()應(yīng)用到具備這個屬性的目標(biāo)對象上(譬如TextView)涩馆。
android:valueTo float、int或者color類型允坚,必須要設(shè)置的節(jié)點屬性魂那,表明動畫結(jié)束的點;如果是顏色的話稠项,由6位十六進(jìn)制的數(shù)字表示涯雅。
android:valueFrom 相對應(yīng)valueTo,動畫的起始點皿渗,如果沒有指定斩芭,系統(tǒng)會通過屬性的get方法獲取轻腺,顏色也是6位十六進(jìn)制的數(shù)字表示乐疆。
android:duration 動畫的時長,int類型贬养,以毫秒為單位挤土,默認(rèn)為300毫秒。
android:startOffset 動畫延遲的時間误算,從調(diào)用start方法后開始計算仰美,int型,毫秒為單位儿礼。
android:repeatCount 一個動畫的重復(fù)次數(shù)咖杂,int型,”-1“表示無限循環(huán)蚊夫,”1“表示動畫在第一次執(zhí)行完成后重復(fù)執(zhí)行一次诉字,也就是兩次,默認(rèn)為0,不重復(fù)執(zhí)行壤圃。
android:repeatMode 重復(fù)模式:int型陵霉,當(dāng)一個動畫執(zhí)行完的時候應(yīng)該如何處理。該值必須是正數(shù)或者是-1伍绳,“reverse”會使得按照動畫向相反的方向執(zhí)行踊挠,可實現(xiàn)類似鐘擺效果〕迳保“repeat”會使得動畫每次都從頭開始循環(huán)效床。
android:valueType 關(guān)鍵參數(shù),如果該value是一個顏色权谁,那么就不需要指定扁凛,因為動畫框架會自動的處理顏色值。有intType和floatType(默認(rèn))兩種:分別說明動畫值為int和float型闯传。

<objectAnimator>屬性解釋:
同上<objectAnimator>屬性谨朝,不多介紹。

XML屬性動畫使用方法:

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
    R.animtor.property_animator);
set.setTarget(myObject);
set.start();

4-2-3 Java方式屬性動畫

1甥绿、ObjectAnimator:繼承自ValueAnimator字币,允許你指定要進(jìn)行動畫的對象以及該對象 的一個屬性。該類會根據(jù)計算得到的新值自動更新屬性共缕。大多數(shù)的情況使用ObjectAnimator就足夠了洗出,因為它使得目標(biāo)對象動畫值的處理過程變得足 夠簡單,不用像ValueAnimator那樣自己寫動畫更新的邏輯图谷,但是ObjectAnimator有一定的限制翩活,比如它需要目標(biāo)對象的屬性提供指定 的處理方法(譬如提供getXXX,setXXX方法)便贵,這時候你就需要根據(jù)自己的需求在ObjectAnimator和ValueAnimator中看 哪種實現(xiàn)更方便了菠镇。

ObjectAnimator類提供了ofInt、ofFloat承璃、ofObject這個三個常用的方法利耍,這些方法都是設(shè)置動畫作用的元素、屬性盔粹、開始隘梨、結(jié)束等任意屬性值。當(dāng)屬性值(上面方法的參數(shù))只設(shè)置一個時就把通過getXXX反射獲取的值作為起點舷嗡,設(shè)置的值作為終點轴猎;如果設(shè)置兩個(參數(shù)),那么一個是開始进萄、另一個是結(jié)束捻脖。

特別注意:ObjectAnimator的動畫原理是不停的調(diào)用setXXX方法更新屬性值烦秩,所有使用ObjectAnimator更新屬性時的前提是Object必須聲明有g(shù)etXXX和setXXX方法。

我們通常使用ObjectAnimator設(shè)置View已知的屬性來生成動畫郎仆,而一般View已知屬性變化時都會主動觸發(fā)重繪圖操作只祠,所以動畫會自 動實現(xiàn);但是也有特殊情況扰肌,譬如作用Object不是View抛寝,或者作用的屬性沒有觸發(fā)重繪,或者我們在重繪時需要做自己的操作曙旭,那都可以通過如下方法手 動設(shè)置:

ObjectAnimator mObjectAnimator= ObjectAnimator.ofInt(view, "customerDefineAnyThingName", 0,  1).setDuration(2000);
mObjectAnimator.addUpdateListener(new AnimatorUpdateListener()
        {
            @Override
            public void onAnimationUpdate(ValueAnimator animation)
            {
                //int value = animation.getAnimatedValue();  可以獲取當(dāng)前屬性值
                //view.postInvalidate();  可以主動刷新
                //view.setXXX(value);
                //view.setXXX(value);
                //......可以批量修改屬性
            }
        });

如下是一個我在項目中的Y軸3D旋轉(zhuǎn)動畫實現(xiàn)實例:

ObjectAnimator.ofFloat(view, "rotationY", 0.0f, 360.0f).setDuration(1000).start();

2盗舰、PropertyValuesHolder:多屬性動畫同時工作管理類。有時候我們需要同時修改多個屬性桂躏,那就可以用到此類钻趋,具體如下:

PropertyValuesHolder a1 = PropertyValuesHolder.ofFloat("alpha", 0f, 1f);  
PropertyValuesHolder a2 = PropertyValuesHolder.ofFloat("translationY", 0, viewWidth);  
......
ObjectAnimator.ofPropertyValuesHolder(view, a1, a2, ......).setDuration(1000).start();

如上代碼就可以實現(xiàn)同時修改多個屬性的動畫啦。

3剂习、ValueAnimator:屬性動畫中的時間驅(qū)動蛮位,管理著動畫時間的開始、結(jié)束屬性值鳞绕,相應(yīng)時間屬性值計算方法等失仁。包含所有計算動畫值的核心函數(shù)以及每一個動畫時間節(jié)點上的信息、一個動畫是否重復(fù)们何、是否監(jiān)聽更新事件等萄焦,并且還可以設(shè)置自定義的計算類型。

特別注意:ValueAnimator只是動畫計算管理驅(qū)動冤竹,設(shè)置了作用目標(biāo)拂封,但沒有設(shè)置屬性,需要通過updateListener里設(shè)置屬性才會生效鹦蠕。

ValueAnimator animator = ValueAnimator.ofFloat(0, mContentHeight);  //定義動畫
animator.setTarget(view);   //設(shè)置作用目標(biāo)
animator.setDuration(5000).start();
animator.addUpdateListener(new AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation){
        float value = (float) animation.getAnimatedValue();
        view.setXXX(value);  //必須通過這里設(shè)置屬性值才有效
        view.mXXX = value;  //不需要setXXX屬性方法
    }
});

大眼看上去可以發(fā)現(xiàn)和ObjectAnimator沒啥區(qū)別冒签,實際上正是由于ValueAnimator不直接操作屬性值,所以要操作對象的屬性可以不需要setXXX與getXXX方法片部,你完全可以通過當(dāng)前動畫的計算去修改任何屬性镣衡。

4、AnimationSet:動畫集合档悠,提供把多個動畫組合成一個組合的機(jī)制,并可設(shè)置動畫的時序關(guān)系望浩,如同時播放辖所、順序播放或延遲播放。具體使用方法比較簡單磨德,如下:

ObjectAnimator a1 = ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0f);  
ObjectAnimator a2 = ObjectAnimator.ofFloat(view, "translationY", 0f, viewWidth);  
......
AnimatorSet animSet = new AnimatorSet();  
animSet.setDuration(5000);  
animSet.setInterpolator(new LinearInterpolator());   
//animSet.playTogether(a1, a2, ...); //兩個動畫同時執(zhí)行  
animSet.play(a1).after(a2); //先后執(zhí)行
......//其他組合方式
animSet.start();  

5缘回、Evaluators相關(guān)類解釋: Evaluators就是屬性動畫系統(tǒng)如何去計算一個屬性值吆视。它們通過Animator提供的動畫的起始和結(jié)束值去計算一個動畫的屬性值。

  • IntEvaluator:整數(shù)屬性值酥宴。

  • FloatEvaluator:浮點數(shù)屬性值啦吧。

  • ArgbEvaluator:十六進(jìn)制color屬性值。

  • TypeEvaluator:用戶自定義屬性值接口拙寡,譬如對象屬性值類型不是int授滓、float、color類型肆糕,你必須實現(xiàn)這個接口去定義自己的數(shù)據(jù)類型般堆。

既然說到這了,那就來個例子吧诚啃,譬如我們需要實現(xiàn)一個自定義屬性類型和計算規(guī)則的屬性動畫淮摔,如下類型float[]:

ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(5000);
valueAnimator.setObjectValues(new float[2]); //設(shè)置屬性值類型
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setEvaluator(new TypeEvaluator<float[]>()
{
    @Override
    public float[] evaluate(float fraction, float[] startValue,
                            float[] endValue)
    {
        //實現(xiàn)自定義規(guī)則計算的float[]類型的屬性值
        float[] temp = new float[2];
        temp[0] = fraction * 2;
        temp[1] = (float)Math.random() * 10 * fraction;
        return temp;
    }
});

valueAnimator.start();
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
    @Override
    public void onAnimationUpdate(ValueAnimator animation)
    {
        float[] xyPos = (float[]) animation.getAnimatedValue();
        view.setHeight(xyPos[0]);   //通過屬性值設(shè)置View屬性動畫
        view.setWidth(xyPos[1]);    //通過屬性值設(shè)置View屬性動畫
    }
});

6、Interpolators相關(guān)類解釋:

  • AccelerateDecelerateInterolator:先加速后減速始赎。

  • AccelerateInterpolator:加速和橙。

  • DecelerateInterpolator:減速。

  • AnticipateInterpolator:先向相反方向改變一段再加速播放造垛。

  • AnticipateOvershootInterpolator:先向相反方向改變胃碾,再加速播放,會超出目標(biāo)值然后緩慢移動至目標(biāo)值筋搏,類似于彈簧回彈仆百。

  • BounceInterpolator:快到目標(biāo)值時值會跳躍。

  • CycleIinterpolator:動畫循環(huán)一定次數(shù)奔脐,值的改變?yōu)橐徽液瘮?shù):Math.sin(2 * mCycles * Math.PI * input)俄周。

  • LinearInterpolator:線性均勻改變。

  • OvershottInterpolator:最后超出目標(biāo)值然后緩慢改變到目標(biāo)值髓迎。

  • TimeInterpolator:一個允許自定義Interpolator的接口峦朗,以上都實現(xiàn)了該接口。

舉個例子排龄,就像系統(tǒng)提供的標(biāo)準(zhǔn)API一樣波势,如下就是加速插值器的實現(xiàn)代碼,我們自定義時也可以類似實現(xiàn):

//開始很慢然后不斷加速的插值器橄维。
public class AccelerateInterpolator implements Interpolator {
    private final float mFactor;
    private final double mDoubleFactor;

    public AccelerateInterpolator() {
        mFactor = 1.0f;
        mDoubleFactor = 2.0;
    }

    ......

    //input  0到1.0尺铣。表示動畫當(dāng)前點的值,0表示開頭争舞,1表示結(jié)尾凛忿。
    //return  插值。值可以大于1超出目標(biāo)值竞川,也可以小于0突破低值店溢。
    @Override
    public float getInterpolation(float input) {
        //實現(xiàn)核心代碼塊
        if (mFactor == 1.0f) {
            return input * input;
        } else {
            return (float)Math.pow(input, mDoubleFactor);
        }
    }
}

綜上可以發(fā)現(xiàn)叁熔,我們可以使用現(xiàn)有系統(tǒng)提供標(biāo)準(zhǔn)的東東實現(xiàn)屬性動畫,也可以通過自定義繼承相關(guān)接口實現(xiàn)自己的動畫床牧,只要實現(xiàn)上面提到的那些主要方法即可荣回。

4-2-4 Java屬性動畫拓展之ViewPropertyAnimator動畫

在Android API 12時,View中添加了animate方法戈咳,具體如下:

public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {
     ......
     /**
     * This method returns a ViewPropertyAnimator object, which can be used to animate
     * specific properties on this View.
     *
     * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.
     */
    public ViewPropertyAnimator animate() {
        if (mAnimator == null) {
            mAnimator = new ViewPropertyAnimator(this);
        }
        return mAnimator;
    }
    ......
}

可以看見通過View的animate()方法可以得到一個ViewPropertyAnimator的屬性動畫(有人說他沒有繼承Animator類心软,是的,他是成員關(guān)系除秀,不是之前那種繼承關(guān)系)糯累。

ViewPropertyAnimator提供了一種非常方便的方法為View的部分屬性設(shè)置動畫(切記,是部分屬性)册踩,它可以直接使用一個 Animator對象設(shè)置多個屬性的動畫泳姐;在多屬性設(shè)置動畫時,它比 上面的ObjectAnimator更加牛逼暂吉、高效胖秒,因為他會管理多個屬性的invalidate方法統(tǒng)一調(diào)運觸發(fā),而不像上面分別調(diào)用慕的,所以還會有一些 性能優(yōu)化阎肝。如下就是一個例子:

myView.animate().x(0f).y(100f).start(); 

4-2-5 Java屬性動畫拓展之LayoutAnimator容器布局動畫

Property動畫系統(tǒng)還提供了對ViewGroup中View添加時的動畫功能,我們可以用LayoutTransition對 ViewGroup中的View進(jìn)行動畫設(shè)置顯示肮街。LayoutTransition的動畫效果都是設(shè)置給ViewGroup风题,然后當(dāng)被設(shè)置動畫的 ViewGroup中添加刪除View時體現(xiàn)出來。該類用于當(dāng)前布局容器中有View添加嫉父、刪除沛硅、隱藏、顯示等時候定義布局容器自身的動畫和View的動 畫绕辖,也就是說當(dāng)在一個LinerLayout中隱藏一個View的時候摇肌,我們可以自定義 整個由于LinerLayout隱藏View而改變的動畫,同時還可以自定義被隱藏的View自己消失時候的動畫等仪际。

我們可以發(fā)現(xiàn)LayoutTransition類中主要有五種容器轉(zhuǎn)換動畫類型围小,具體如下:

  • LayoutTransition.APPEARING:當(dāng)View出現(xiàn)或者添加的時候View出現(xiàn)的動畫。

  • LayoutTransition.CHANGE_APPEARING:當(dāng)添加View導(dǎo)致布局容器改變的時候整個布局容器的動畫树碱。

  • LayoutTransition.DISAPPEARING:當(dāng)View消失或者隱藏的時候View消失的動畫肯适。

  • LayoutTransition.CHANGE_DISAPPEARING:當(dāng)刪除或者隱藏View導(dǎo)致布局容器改變的時候整個布局容器的動畫。

  • LayoutTransition.CHANGE:當(dāng)不是由于View出現(xiàn)或消失造成對其他View位置造成改變的時候整個布局容器的動畫赴恨。

XML方式使用系統(tǒng)提供的默認(rèn)LayoutTransition動畫:

我們可以通過如下方式使用系統(tǒng)提供的默認(rèn)ViewGroup的LayoutTransition動畫:

android:animateLayoutChanges=”true”

在ViewGroup添加如上xml屬性默認(rèn)是沒有任何動畫效果的疹娶,因為前面說了,該動畫針對于ViewGroup內(nèi)部東東發(fā)生改變時才有效伦连,所以當(dāng)我們設(shè)置如上屬性然后調(diào)運ViewGroup的addView雨饺、removeView方法時就能看見系統(tǒng)默認(rèn)的動畫效果了。

還有一種就是通過如下方式設(shè)置:

android:layoutAnimation=”@anim/customer_anim”

通過這種方式就能實現(xiàn)很多吊炸天的動畫惑淳。

Java方式使用系統(tǒng)提供的默認(rèn)LayoutTransition動畫:

在使用LayoutTransition時额港,你可以自定義這幾種事件類型的動畫,也可以使用默認(rèn)的動畫歧焦,總之最終都是通過 setLayoutTransition(LayoutTransition lt)方法把這些動畫以一個LayoutTransition對象設(shè)置給一個ViewGroup移斩。

譬如實現(xiàn)如上Xml方式的默認(rèn)系統(tǒng)LayoutTransition動畫如下:

mTransitioner = new LayoutTransition();
mViewGroup.setLayoutTransition(mTransitioner);

稍微再高端一點吧,我們來自定義這幾類事件的動畫绢馍,分別實現(xiàn)他們向瓷,那么你可以像下面這么處理:

mTransitioner = new LayoutTransition();
......
ObjectAnimator anim = ObjectAnimator.ofFloat(this, "scaleX", 0, 1);
......//設(shè)置更多動畫
mTransition.setAnimator(LayoutTransition.APPEARING, anim);
......//設(shè)置更多類型的動畫                mViewGroup.setLayoutTransition(mTransitioner);

到此通過LayoutTransition你就能實現(xiàn)類似小米手機(jī)計算器切換普通型和科學(xué)型的炫酷動畫了。

5 Android動畫總結(jié)

到此Android動畫基本已經(jīng)描述OK了舰涌,也就這么三大類猖任,尤其是屬性動畫更加一籌。但是特別說一句瓷耙,上面基本都沒有提及到各種動畫的 Listener接口朱躺,原因是這個玩意太簡單,所以不提了搁痛,相信你會監(jiān)聽View的onClickListener就一定會觸類旁通動畫的 Listener方法的长搀。有了這些基礎(chǔ)相信無論是自定義控件時還是自定義動畫時都會起到直接的指導(dǎo)參考作用。其實對于Android的動畫實現(xiàn)遠(yuǎn)遠(yuǎn)不止現(xiàn) 在提到的這些鸡典,但是這些又是基礎(chǔ)源请,所以后面還會寫文章說說Android提供的其他動畫參考工具類的。

現(xiàn)在我們繼續(xù)沿用官方的對比彻况,翻譯一下這些動畫的區(qū)別谁尸,具體如下(點我參看原文How Property Animation Differs from View Animation):

View動畫:

View動畫只能夠為View添加動畫,如果想為非View對象添加動畫須自己實現(xiàn)疗垛;且View動畫支持的種類很少症汹;尤其是他改變的是View的繪制效果,View的屬性沒有改變贷腕,其位置與大小都不變背镇; View動畫代碼量少,使用簡單方便泽裳。

Property動畫:

彌補(bǔ)了View動畫的缺陷瞒斩,你可以為一個對象的任意屬性添加動畫,對象自己的屬性會被真的改變涮总;當(dāng)對象的屬性變化的時候胸囱,屬性動畫會自動刷新屏幕;屬性動畫改變的是對象的真實屬性瀑梗,而且屬性動畫不止用于View烹笔,還可以用于任何對象裳扯。

本文轉(zhuǎn)載自:https://www.cnblogs.com/ldq2016/p/5407061.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谤职,隨后出現(xiàn)的幾起案子饰豺,更是在濱河造成了極大的恐慌,老刑警劉巖允蜈,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冤吨,死亡現(xiàn)場離奇詭異,居然都是意外死亡饶套,警方通過查閱死者的電腦和手機(jī)漩蟆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妓蛮,“玉大人怠李,你說我怎么就攤上這事∽幸” “怎么了扔仓?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長咖耘。 經(jīng)常有香客問我翘簇,道長,這世上最難降的妖魔是什么儿倒? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任版保,我火速辦了婚禮,結(jié)果婚禮上夫否,老公的妹妹穿的比我還像新娘彻犁。我一直安慰自己,他們只是感情好凰慈,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布汞幢。 她就那樣靜靜地躺著,像睡著了一般微谓。 火紅的嫁衣襯著肌膚如雪森篷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天豺型,我揣著相機(jī)與錄音仲智,去河邊找鬼。 笑死姻氨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播功戚,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蛀恩,長吁一口氣:“原來是場噩夢啊……” “哼疫铜!你這毒婦竟也來了双谆?” 一聲冷哼從身側(cè)響起席揽,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤顽馋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后寸谜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體属桦,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡聂宾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年系谐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鄙煤。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡梯刚,死狀恐怖亡资,靈堂內(nèi)的尸體忽然破棺而出预愤,到底是詐尸還是另有隱情植康,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布供璧,位于F島的核電站,受9級特大地震影響来惧,放射性物質(zhì)發(fā)生泄漏供搀。R本人自食惡果不足惜钠至,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一屿脐、第九天 我趴在偏房一處隱蔽的房頂上張望宪卿。 院中可真熱鬧佑钾,春花似錦、人聲如沸瘪阁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泻云。三九已至宠纯,卻和暖如春婆瓜,著一層夾襖步出監(jiān)牢的瞬間贡羔,已是汗流浹背乖寒。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工楣嘁, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留珍逸,地道東北人弄息。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓摹量,卻偏偏與公主長得像馒胆,于是被迫代替她去往敵國和親祝迂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 1 背景 不能只分析源碼呀,分析的同時也要整理歸納基礎(chǔ)知識沿量,剛好有人微博私信讓全面說說Android的動畫冤荆,所以今...
    未聞椛洺閱讀 2,718評論 0 10
  • 1 背景 不能只分析源碼呀钓简,分析的同時也要整理歸納基礎(chǔ)知識外邓,剛好有人微博私信讓全面說說Android的動畫损话,所以今...
    lisx_閱讀 965評論 0 0
  • 轉(zhuǎn)載一篇高質(zhì)量博文,原地址請戳這里轉(zhuǎn)載下來方便今后查看夏漱。1 背景不能只分析源碼呀顶捷,分析的同時也要整理歸納基礎(chǔ)知識服赎,...
    Elder閱讀 1,943評論 0 24
  • View Animation(視圖動畫) 概述: 視圖動畫重虑,也叫 Tween (補(bǔ)間)動畫可以在一個視圖容器內(nèi)執(zhí)行...
    ZoranLee閱讀 850評論 0 1
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月桩皿,有人笑有人哭痕届,有人歡樂有人憂愁土匀,有人驚喜有人失落辐脖,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,545評論 28 53