首先附上谷歌官方文檔鏈接地址
在Android中,一個(gè)動(dòng)畫(huà)資源可由兩種形式的動(dòng)畫(huà)之一確定:屬性動(dòng)畫(huà)(Property Animation)和視圖動(dòng)畫(huà)(View Animation);
視圖動(dòng)畫(huà)又包含了兩種形式的動(dòng)畫(huà):幀動(dòng)畫(huà)(Frame animation)和補(bǔ)間動(dòng)畫(huà)(Tween animation).
In this document
Property Animation
View Animation
Tween animation
Frame animation
一、幀動(dòng)畫(huà)(Frame animation)
先來(lái)看看谷歌的官方定義:An animation defined in XML that shows a sequence of images in order (like a film).(在XML文件中定義的用于按次序播放一系列圖片(類(lèi)似于電影)的動(dòng)畫(huà))。顯然這是一個(gè)傳統(tǒng)動(dòng)畫(huà),它創(chuàng)建一個(gè)個(gè)不同的圖像序列并有序的播放,類(lèi)似于早期動(dòng)畫(huà)片的原理。
??幀動(dòng)畫(huà)可以定義在XML中并在代碼中實(shí)現(xiàn),如果我們要在XML中定義幀動(dòng)畫(huà),需在res/drawable/filename.xml文件下,文件名會(huì)被用作資源ID;如果完全由代碼實(shí)現(xiàn)的話,就要用到AnimationDrawable對(duì)象。
resource reference:
In Java: R.drawable.filename
In XML: @[package:]drawable.filename
將動(dòng)畫(huà)定義在XML中官方給出的語(yǔ)法規(guī)范示例:
<?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>
元素及必要屬性:
<animation-list>元素:
必要元素,包含一個(gè)或多個(gè)<item>元素。
包含屬性:
android:oneshot
boolean值,“true”表示播放動(dòng)畫(huà)一次,“false”表示循環(huán)播放動(dòng)畫(huà)。
<item>元素:
一幀動(dòng)畫(huà),必須是<animation-list>元素的子元素。
包含屬性:
android:drawable
圖片資源,表示這一幀代表的圖片
android:duration
整形值,表示展示這一幀的的時(shí)間,以毫秒為單位。
然后官方給出了示例代碼:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
<item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
<item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>
上面幀動(dòng)畫(huà)中共有三張圖片,每張停留200毫秒并且循環(huán)播放。我們?cè)诖a中會(huì)將上述動(dòng)畫(huà)設(shè)置為背景視圖,現(xiàn)在我們?cè)诖a中播放上述動(dòng)畫(huà):
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
rocketAnimation.start();
OK,關(guān)于幀動(dòng)畫(huà)的部分基本介紹完了,相對(duì)比較簡(jiǎn)單,上面基本是翻譯的官方文檔。
??另外需要注意的一點(diǎn)是:如果我們將rocketAnimation.start();放在Activity的onCreate()函數(shù)中,在低版本的安卓設(shè)備上(4X以下)可能會(huì)出現(xiàn)問(wèn)題(如動(dòng)畫(huà)會(huì)停留在第一幀等)因?yàn)锳nimationDrawable的start方法時(shí),窗口Window對(duì)象還沒(méi)有完全初始化,AnimationDrawable不能完全追加到窗口Window對(duì)象中,官網(wǎng)給出的建議是在Activity的onWindowFocusChanged方法(如果對(duì)此方法不熟可以看此博客http://blog.csdn.net/dmk877/article/details/45059261)中去掉用AnimationDrawable.start()方法,因?yàn)閛nWindowFocusChanged在Activity窗口獲得或失去焦點(diǎn)時(shí)調(diào)用,例如創(chuàng)建時(shí)首次展示在用戶面前,所以在調(diào)用onWindowFocusChanged方法時(shí)窗口已經(jīng)初始化完全了。當(dāng)然如果不適配那么低的版本的設(shè)備的話我們可以不必考慮這個(gè)問(wèn)題。(這段參考自博客http://blog.csdn.net/dmk877/article/details/45893017)。
二、補(bǔ)間動(dòng)畫(huà)(Tween animation)
我們先來(lái)看看官方對(duì)于補(bǔ)間動(dòng)畫(huà)的定義:
Creates an animation by performing a series of transformations on a single image with an Animation(通過(guò)對(duì)單張圖片執(zhí)行一系列的轉(zhuǎn)變來(lái)創(chuàng)造一個(gè)動(dòng)畫(huà))
An animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic(一個(gè)定義在XML文件中,通過(guò)執(zhí)行諸如旋轉(zhuǎn),淡變(透明度),移動(dòng)和圖形拉伸創(chuàng)造的動(dòng)畫(huà))
同樣文件位置在**res/anim/filename.xml**中,
resource reference:
In Java: R.anim.filename
In XML: @[package:]anim/filename
語(yǔ)法規(guī)范:
<?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>
上述代碼塊可以看出,補(bǔ)間動(dòng)畫(huà)分為四類(lèi):alpha(漸變)、scale(縮放)、translate(位移)、rotate(旋轉(zhuǎn)),這四種動(dòng)畫(huà)既有他獨(dú)有的屬性同時(shí)又有animation類(lèi)的通用屬性。
The file must have a single root element: either an <alpha>, <scale>, <translate>, <rotate>,
or <set> element that holds a group (or groups) of other animation elements (even nested <set> elements).
此文件必須含有alpha,scale,translate或者rotate中的一個(gè)根元素,或者含有一個(gè)包含了一組或者更多組的其他動(dòng)畫(huà)元素(甚至是嵌套的<set>元素)。
從Animation類(lèi)繼承的共有屬性 :
android:duration:動(dòng)畫(huà)執(zhí)行的時(shí)間,以毫秒為單位
android:fillEnabled:true|false,true:動(dòng)畫(huà)結(jié)束時(shí)還原到開(kāi)始動(dòng)畫(huà)前的狀態(tài)
android:fillBefore:如果fillEnabled的值為true,它的值才有意義,否則沒(méi)有意義默認(rèn)值是true,視圖會(huì)停留在動(dòng)畫(huà)開(kāi)始的狀態(tài)
android:fillAfter:設(shè)置的是在這個(gè)動(dòng)畫(huà)結(jié)束后是否保留這個(gè)動(dòng)畫(huà)的最后一幀的效果填充后面的動(dòng)畫(huà),它的設(shè)置不受fillEnabled的影響
android:repeatMode:reverse|restart,重復(fù)類(lèi)型,reverse:表示倒序回訪,restart:表示重新放一遍,這個(gè)屬性必須與repeatCount聯(lián)合使用,因?yàn)樗那疤崾侵貜?fù),即重復(fù)播放時(shí)的播放類(lèi)型。
android:repeatCount:動(dòng)畫(huà)重復(fù)的次數(shù)(注意是重復(fù)的次數(shù)),可以是你想循環(huán)播放的次數(shù),也是可以是infinite:表示無(wú)限循環(huán)
android:interpolator:設(shè)定的插值器,它主要用來(lái)為動(dòng)畫(huà)設(shè)置一些特殊的效果,比方說(shuō):加速運(yùn)動(dòng)、減速運(yùn)動(dòng)、動(dòng)畫(huà)結(jié)束的時(shí)候彈 起等等
(1)roate動(dòng)畫(huà),旋轉(zhuǎn)動(dòng)畫(huà)
上面我們交代過(guò)四種動(dòng)畫(huà)有共有屬性和私有屬性,現(xiàn)在我們先講講私有屬性。
這里可以參考roateanimation類(lèi)的說(shuō)明文檔(https://developer.android.com/reference/android/view/animation/RotateAnimation.html)
屬性:
android:fromDegrees
Float. Starting angular position, in degrees.
動(dòng)畫(huà)開(kāi)始時(shí)的旋轉(zhuǎn)的角度位置,浮點(diǎn)類(lèi)型,正值代表順時(shí)針?lè)较虻亩葦?shù),負(fù)值代表逆時(shí)針。
android:toDegrees
Float. Starting angular position, in degrees.
動(dòng)畫(huà)結(jié)束時(shí)旋轉(zhuǎn)到的角度位置,float類(lèi)型,正值代表順時(shí)針?lè)较蚨葦?shù),負(fù)值代碼逆時(shí)針?lè)较蚨葦?shù)
android:pivotX
Float or percentage. The X coordinate of the center of rotation. Expressed either: in pixels relative to the object's left edge (such as "5"), in percentage relative to the object's left edge (such as "5%"), or in percentage relative to the parent container's left edge (such as "5%p").
表示的事旋轉(zhuǎn)點(diǎn)的X軸坐標(biāo),可以是數(shù)值、百分?jǐn)?shù)、百分?jǐn)?shù)p三種樣式,比如50、50%、50%p。如果為數(shù)值,表示當(dāng)前View的左上角(Android中View的原點(diǎn))加上50px作為旋轉(zhuǎn)點(diǎn)X坐標(biāo);如果是50%,表示當(dāng)前View的左上角加上自己寬度的50%作為旋轉(zhuǎn)點(diǎn)的X坐標(biāo);如果是50%p,則表示在當(dāng)前控件的左上角加上父控件寬度的50%作為旋轉(zhuǎn)點(diǎn)X坐標(biāo)。
android:pivotY
和pivotX 同理,這里不再獒述。
默認(rèn)的旋轉(zhuǎn)起始點(diǎn)是View左上角的視圖原點(diǎn),需要注意的是這里的開(kāi)始旋轉(zhuǎn)角度f(wàn)romDegrees和結(jié)束時(shí)旋轉(zhuǎn)角度都是相對(duì)于其實(shí)位置而言的。
可以參考這篇博客:http://blog.csdn.net/dmk877/article/details/51912104,講的很好很全面。
(2)Alpha動(dòng)畫(huà)(漸變透明度動(dòng)畫(huà))
一種淡入或者淡出的動(dòng)畫(huà),可以參考AlphaAnimation類(lèi)說(shuō)明文檔https://developer.android.com/reference/android/view/animation/AlphaAnimation.html
屬性說(shuō)明:
android:fromAlpha
Float. Starting opacity offset, where 0.0 is transparent and 1.0 is opaque.
浮點(diǎn)值,表示動(dòng)畫(huà)開(kāi)始時(shí)的透明度,變化范圍從0.0(透明)到1.0(不透明)。
android:toAlpha
Float. Ending opacity offset, where 0.0 is transparent and 1.0 is opaque.
浮點(diǎn)值,表示動(dòng)畫(huà)結(jié)束時(shí)的透明度,取值同上。
(3)translate(位移動(dòng)畫(huà))
A vertical and/or horizontal motion. Supports the following attributes in any of the following three formats: values from -100 to 100 ending with "%", indicating a percentage relative to itself; values from -100 to 100 ending in "%p", indicating a percentage relative to its parent; a float value with no suffix, indicating an absolute value. Represents a TranslateAnimation.https://developer.android.com/reference/android/view/animation/TranslateAnimation.html
??從官方文檔的描述中,我們可以知道:
位移動(dòng)畫(huà)是一種水平或者豎直的運(yùn)動(dòng),他有三種不同的單位表示:第一種是以-100%-100%之間的值來(lái)結(jié)尾,表示移動(dòng)的距離相對(duì)自身;第二種是以-100%p-100%p之間的值,表示移動(dòng)的距離是相對(duì)于父控件;一種是沒(méi)有任何后綴的浮點(diǎn)值,表示移動(dòng)的絕對(duì)距離.這和上面roate中的情況是一樣的.
android:fromXDelta
Float or percentage. Starting X offset. Expressed either: in pixels relative to the normal position (such as "5"), in percentage relative to the element width (such as "5%"), or in percentage relative to the parent width (such as "5%p").
起始點(diǎn)的X軸坐標(biāo),可以是數(shù)值、百分?jǐn)?shù)、百分?jǐn)?shù)p三種形式,具體的已經(jīng)在rotate里邊講過(guò)了,就是相對(duì)于View視圖左上角(原點(diǎn))的偏移量。
android:toXDelta
Float or percentage. Ending X offset. Expressed either: in pixels relative to the normal position (such as "5"), in percentage relative to the element width (such as "5%"), or in percentage relative to the parent width (such as "5%p").
結(jié)束點(diǎn)的X坐標(biāo)。
android:fromYDelta
Float or percentage. Starting Y offset. Expressed either: in pixels relative to the normal position (such as "5"), in percentage relative to the element height (such as "5%"), or in percentage relative to the parent height (such as "5%p").
起始點(diǎn)的Y坐標(biāo)。
android:toYDelta
Float or percentage. Ending Y offset. Expressed either: in pixels relative to the normal position (such as "5"), in percentage relative to the element height (such as "5%"), or in percentage relative to the parent height (such as "5%p").
結(jié)束點(diǎn)的Y坐標(biāo)。
(4)scale縮放動(dòng)畫(huà)
A resizing animation. You can specify the center point of the image from which it grows outward (or inward) by specifying pivotX and pivotY. For example, if these values are 0, 0 (top-left corner), all growth will be down and to the right. Represents a ScaleAnimation.
??一種伸縮動(dòng)畫(huà),你可以精確指定圖片縮放的中心點(diǎn)。
android:fromXScale
Float. Starting X size offset, where 1.0 is no change.
浮點(diǎn)值,起始的X軸方向上相對(duì)自身的縮放比例。(1.0表示沒(méi)有縮放,0.5表示縮小一倍,2表示放大一倍)
android:toXScale
Float. Ending X size offset, where 1.0 is no change.
結(jié)尾的X軸方向上相對(duì)于自身的縮放比例。
android:fromYScale
Float. Starting Y size offset, where 1.0 is no change.
起始方向上Y軸方向上相對(duì)于自身的縮放比例。
android:toYScale
Float. Ending Y size offset, where 1.0 is no change.
結(jié)尾方向上Y軸相對(duì)自身的縮放比例。
android:pivotX
Float. The X coordinate to remain fixed when the object is scaled.
縮放起點(diǎn)X軸坐標(biāo),可以是數(shù)值、百分?jǐn)?shù)、百分?jǐn)?shù)p,具體意義和 roate中的一致。
android:pivotY
Float. The Y coordinate to remain fixed when the object is scaled.
縮放起點(diǎn)Y軸坐標(biāo),取值及意義同pivotX
(5)set標(biāo)簽的使用
set標(biāo)簽是一系列動(dòng)畫(huà)的組合,也就是說(shuō)我們可以通過(guò)set讓一個(gè)View同時(shí)執(zhí)行多張動(dòng)畫(huà),set標(biāo)簽本身是沒(méi)有屬性的,但是他可以使用Animation類(lèi)的屬性。當(dāng) android:shareInterpolator = true時(shí),set標(biāo)簽的屬性會(huì)作用于所有的子元素。(具體的Animation屬性我們后面會(huì)做進(jìn)一步詳解)。
ELEMENTS:
<set>
A container that holds other animation elements (<alpha>, <scale>, <translate>, <rotate>) or other <set> elements. Represents an AnimationSet.
attributes:
android:interpolator 該屬性為一個(gè)指示器,指向一個(gè)動(dòng)畫(huà)資源文件,該值必須是一個(gè)資源文件的引用(就像示例代碼中那樣指向一個(gè)包名)而不是一個(gè)類(lèi)名。
Interpolator resource. An Interpolator to apply on the animation. The value must be a reference to a resource that specifies an interpolator (not an interpolator class name). There are default interpolator resources available from the platform or you can create your own interpolator resource. See the discussion below for more about Interpolators.
android:shareInterpolator 該屬上面已經(jīng)交代過(guò)了。
Boolean. "true" if you want to share the same interpolator among all child elements.
我們來(lái)看看一個(gè)組合動(dòng)畫(huà)的例子
<?xml version="1.0" encoding= "utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<alpha
android:fromAlpha= "0.0"
android:toAlpha= "1.0"
android:duration= "3000" />
<scale
android:fromXScale= "0.0"
android:toXScale= "1.0"
android:fromYScale= "0.0"
android:toYScale= "1.0"
android:pivotX= "50%"
android:pivotY= "50%"
android:duration= "3000" />
<rotate
android:fromDegrees= "0"
android:toDegrees= "720"
android:pivotX= "50%"
android:pivotY= "50%"
android:duration= "3000"/>
<translate
android:startOffset= "3000"
android:fromXDelta= "0"
android:fromYDelta= "0"
android:toXDelta= "85"
android:toYDelta= "0"
android:duration= "1000" />
<alpha
android:startOffset= "4000"
android:fromAlpha= "1.0"
android:toAlpha= "0.0"
android:duration= "1000" />
</set>
在這個(gè)set標(biāo)簽中,我們包含了上面四種不同的動(dòng)畫(huà),當(dāng)我們對(duì)一張圖start()這個(gè)動(dòng)畫(huà)后會(huì)同時(shí)執(zhí)行前三種動(dòng)畫(huà),持續(xù)3S,之后執(zhí)行平移動(dòng)畫(huà)(startOffset= "3000",duration= "1000"),最后執(zhí)行最后一個(gè)漸變動(dòng)畫(huà)(startOffset= "4000").
(6)interpolator插值器
An interpolator is an animation modifier defined in XML that affects the rate of change in an animation. This allows your existing animation effects to be accelerated, decelerated, repeated, bounced, etc.
??An interpolator is applied to an animation element with the android:interpolator attribute, the value of which is a reference to an interpolator resource.
??All interpolators available in Android are subclasses of the Interpolator class. For each interpolator class, Android includes a public resource you can reference in order to apply the interpolator to an animation using the android:interpolator attribute. The following table specifies the resource to use for each interpolator:
??上面官方對(duì)于interpolator的解釋為:一種定義在XML文件中影響動(dòng)畫(huà)變化速率的調(diào)節(jié)器,它允許你對(duì)目前的動(dòng)畫(huà)做出加速、減速、重復(fù)、彈跳等效果。
??一個(gè)插值器通過(guò)android:interpolator屬性來(lái)作用于一個(gè)動(dòng)畫(huà),該屬性作用的值是一個(gè)interpolator資源文件,如上面示例中提到的android:interpolator="@[package:]anim/interpolator_resource"
??在Android中所有可用的interpolator都是Interpolator類(lèi)的子類(lèi).(https://developer.android.com/reference/android/view/animation/Interpolator.html)對(duì)于interpolator類(lèi),Android包含一個(gè)你可以通過(guò) android:interpolator 元素調(diào)用的公共資源文件,下面的這張表指定了指向各個(gè)interpolator的資源。
Interpolator對(duì)象 資源ID 功能作用
AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 先加速再減速
AccelerateInterpolator @android:anim/accelerate_interpolator 加速
AnticipateInterpolator @android:anim/anticipate_interpolator 先回退一小步然后加速前進(jìn)
AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 先回退一小步然后加速前進(jìn),超出終點(diǎn)一小步后再回到終點(diǎn)
BounceInterpolator @android:anim/bounce_interpolator 最后階段彈球效果
CycleInterpolator @android:anim/cycle_interpolator 周期運(yùn)動(dòng)
DecelerateInterpolator @android:anim/decelerate_interpolator 減速
LinearInterpolator @android:anim/linear_interpolator 勻速
OvershootInterpolator @android:anim/overshoot_interpolator 快速到達(dá)終點(diǎn)并超出一小步最后回到終點(diǎn)
我們可以創(chuàng)建一個(gè)插值器資源修改插值器的屬性來(lái)自定義個(gè)性化插值器,比如修改AnticipateInterpolator的加速速率,調(diào)整CycleInterpolator的循環(huán)次數(shù)等。為了完成這種需求,我們需要?jiǎng)?chuàng)建XML資源文件,然后將其放于/res/anim下,然后再動(dòng)畫(huà)元素中引用即可。我們先來(lái)看一下幾種常見(jiàn)的插值器可調(diào)整的屬性:
<accelerateDecelerateInterpolator> 無(wú)
<accelerateInterpolator> android:factor 浮點(diǎn)值,加速速率,默認(rèn)為1
<anticipateInterploator> android:tension 浮點(diǎn)值,起始點(diǎn)后退的張力、拉力數(shù),默認(rèn)為2
<anticipateOvershootInterpolator> android:tension 同上; android:extraTension 浮點(diǎn)值,拉力的倍數(shù),默認(rèn)為1.5(2 * 1.5)
<bounceInterpolator> 無(wú)
<cycleInterplolator> android:cycles 整數(shù)值,循環(huán)的個(gè)數(shù),默認(rèn)為1
<decelerateInterpolator> android:factor 浮點(diǎn)值,減速的速率,默認(rèn)為1
<linearInterpolator> 無(wú)
<overshootInterpolator> 浮點(diǎn)值,超出終點(diǎn)后的張力、拉力,默認(rèn)為2
關(guān)于這幾種值得演示可以再次參考一下這篇博客http://blog.csdn.net/dmk877/article/details/52011155
舉個(gè)例子:
??我們?cè)赬ML中定義一個(gè)Interpolator文件—— res/anim/my_overshoot_interpolator.xml:
<?xml version="1.0" encoding="utf-8"?>
<overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:tension="7.0"
/>
動(dòng)畫(huà)的XML文件中可以這么使用:
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/my_overshoot_interpolator" //一句代碼的事
android:fromXScale="1.0"
android:toXScale="3.0"
android:fromYScale="1.0"
android:toYScale="3.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="700" />
這里我們修改了超出終點(diǎn)后張力、拉力的值為7.0,運(yùn)行后會(huì)發(fā)現(xiàn)明顯回彈的效果會(huì)更加急促。
以上就是補(bǔ)間動(dòng)畫(huà)在XML文件中的定義與使用,關(guān)于補(bǔ)間動(dòng)畫(huà)在JAVA代碼中的使用可以參考這篇文章:http://blog.csdn.net/dmk877/article/details/51980734
三、屬性動(dòng)畫(huà)(Property Animation)
https://developer.android.com/guide/topics/graphics/prop-animation.html#value-animator
1.屬性動(dòng)畫(huà)與視圖動(dòng)畫(huà)的區(qū)別
??前面我們說(shuō)過(guò)Android動(dòng)畫(huà)分為視圖動(dòng)畫(huà)(View Animation)和屬性動(dòng)畫(huà)(Property Animation),現(xiàn)在我們來(lái)談?wù)剬傩詣?dòng)畫(huà)這個(gè)大類(lèi)。首先我們分清楚屬性動(dòng)畫(huà)和視圖動(dòng)畫(huà)的區(qū)別,在谷歌的官方說(shuō)明中的解釋如下:
??①The view animation system provides the capability to only animate View objects, so if you wanted to animate non-View objects, you have to implement your own code to do so. The view animation system is also constrained in the fact that it only exposes a few aspects of a View object to animate, such as the scaling and rotation of a View but not the background color, for instance.
??View動(dòng)畫(huà)只提供了容納View對(duì)象的容器,如果你想作用于非View對(duì)象時(shí),你必須自己通過(guò)代碼來(lái)實(shí)現(xiàn)。View動(dòng)畫(huà)另一個(gè)不足是他只暴露了幾個(gè)方面的動(dòng)效給View對(duì)象,諸如平移旋轉(zhuǎn)等,而不是View的背景顏色等等。
??官方翻譯比較繞,這里在翻譯一下,就是說(shuō)補(bǔ)間動(dòng)畫(huà)只能對(duì)一個(gè)View對(duì)象進(jìn)行四種操作(平移、旋轉(zhuǎn)、透明度、縮放),而不能是一個(gè)對(duì)象的屬性,比如顏色,大小等,但是屬性動(dòng)畫(huà)就可以。
??②Another disadvantage of the view animation system is that it only modified where the View was drawn, and not the actual View itself. For instance, if you animated a button to move across the screen, the button draws correctly, but the actual location where you can click the button does not change, so you have to implement your own logic to handle this.
??另一個(gè)弊端是View動(dòng)畫(huà)只能改變View繪制的地方,并不是真正的View本身。舉個(gè)例子,如果你做一個(gè)穿過(guò)屏幕的Button動(dòng)效,Button的繪制時(shí)是正確的,但是Button的實(shí)際可以點(diǎn)擊的位置是沒(méi)有變的,所以你得通過(guò)自己的邏輯來(lái)解決這個(gè)問(wèn)題(就是說(shuō)你還是得點(diǎn)擊原來(lái)Button的位置才會(huì)有相應(yīng)的響應(yīng)事件)。
??③With the property animation system, these constraints are completely removed, and you can animate any property of any object (Views and non-Views) and the object itself is actually modified. The property animation system is also more robust in the way it carries out animation. At a high level, you assign animators to the properties that you want to animate, such as color, position, or size and can define aspects of the animation such as interpolation and synchronization of multiple animators.
??通過(guò)屬性動(dòng)畫(huà)系統(tǒng),這些約束將被徹底解除,你可以對(duì)任何對(duì)象(Views and non-Views)的任何屬性做動(dòng)畫(huà)效果,并且對(duì)象自身也會(huì)被實(shí)際的改變。屬性動(dòng)畫(huà)系統(tǒng)在具體實(shí)施動(dòng)畫(huà)方面也是更加強(qiáng)大的。從更高層次來(lái)說(shuō),你可以選擇你想要的屬性來(lái)給其添加動(dòng)畫(huà),諸如顏色、位置或者尺寸,并且你可以通過(guò)多個(gè)插值器和定義多個(gè)動(dòng)畫(huà)同步來(lái)實(shí)現(xiàn)特定方面的動(dòng)畫(huà)。
2.具體類(lèi)
??屬性動(dòng)畫(huà)常用的類(lèi)有:ValueAnimator, ObjectAnimator, or AnimatorSet.這三個(gè)類(lèi)可以通過(guò)一張圖來(lái)很好的解釋
可以看到,ValueAnimator和AnimatorSet是繼承自Animator類(lèi)的,并且位于同一等級(jí);ObjectAnimator和TimeAnimator是繼承自ValueAnimator類(lèi)的,兩者位于同一等級(jí)。
(1)ValueAnimator
(https://developer.android.com/reference/android/animation/ValueAnimator.html)
??This class provides a simple timing engine for running animations which calculate animated values and set them on target objects. 該類(lèi)通過(guò)通過(guò)計(jì)算動(dòng)效值為運(yùn)動(dòng)的動(dòng)畫(huà)提供了一個(gè)簡(jiǎn)單的時(shí)間引擎,并將其作用于目標(biāo)對(duì)象上面。
??The ValueAnimator class lets you animate values of some type for the duration of an animation by specifying a set of int, float, or color values to animate through. You obtain a ValueAnimator by calling one of its factory methods: **ofInt(), ofFloat(), **or ofObject()
??ValueAnimator類(lèi)讓你在動(dòng)畫(huà)運(yùn)行期間通過(guò)指定int,float或者顏色值來(lái)確定動(dòng)畫(huà)值。你可以通過(guò)調(diào)用ofInt(), ofFloat(), 或者 ofObject()這三個(gè)方法來(lái)獲得一個(gè)ValueAnimator。例如:
ValueAnimator valueAnimator=ValueAnimator.ofFloat(0,100);
valueAnimator.setDuration(3000);
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value=(Float) animation.getAnimatedValue();
ivImage.setTranslationX(value);
}
});
valueAnimator.start();
這段代碼中我們?cè)O(shè)置了一個(gè)動(dòng)畫(huà)值從0變到100的,持續(xù)時(shí)間3S的動(dòng)畫(huà)屬性,然后給這個(gè)ValueAnimator設(shè)置一個(gè)監(jiān)聽(tīng)器,
通過(guò)getAnimatedValue()取得動(dòng)畫(huà)值并將其通過(guò)getAnimatedValue()設(shè)置給了ImageView對(duì)象在X軸的坐標(biāo),運(yùn)行后會(huì)看
到這個(gè)ImageView在X軸上移動(dòng)了100px.
啊,好吧,看過(guò)本人蹩手蹩腳的翻譯之后相信你已經(jīng)是一頭霧水了,上面提到了ValueAnimator類(lèi)的三個(gè)常用的方法:ofFloat,ofInt,ofObject.
①ValueAnimator ofInt (int... values)
Parameters
**values int: **A set of values that the animation will animate between over time.
??這是一組可變參數(shù),當(dāng)然參數(shù)的是Int類(lèi)型。我們可以傳任何值進(jìn)去,傳進(jìn)去的值列表,就表示動(dòng)畫(huà)播放時(shí)代的變化范圍,比如ofInt(3,9,6)就表示從數(shù)值3變化到數(shù)值9再變化到數(shù)值6。
Returns
ValueAnimator ** A ValueAnimator object that is set up to animate between the given values.
??返回一個(gè)ValueAnimator對(duì)象,給誰(shuí)設(shè)置的值就返回誰(shuí)。
②ValueAnimator ofFloat (float... values) 參數(shù)意義同上
Parameters
values float: A set of values that the animation will animate between over time.
Returns
ValueAnimator ** A ValueAnimator object that is set up to animate between the given values.
③ValueAnimator ofObject (TypeEvaluator evaluator, Object... values)
??這里第一個(gè)參數(shù)是TypeEvaluator類(lèi) (https://developer.android.com/reference/android/animation/TypeEvaluator.html)
關(guān)于這個(gè)動(dòng)畫(huà)我們后面暫時(shí)用不到,我們后面再說(shuō)。
??ValueAnimator是計(jì)算動(dòng)畫(huà)過(guò)程中變化的值,包含動(dòng)畫(huà)的開(kāi)始值,結(jié)束值,持續(xù)時(shí)間等屬性。但是這些值與我們的控件是無(wú)關(guān)的,要想把計(jì)算出來(lái)的值應(yīng)用到對(duì)象上,必須為ValueAnimator注冊(cè)一個(gè)監(jiān)聽(tīng)器,該監(jiān)聽(tīng)器負(fù)責(zé)更新對(duì)象的屬性值。在實(shí)現(xiàn)這個(gè)監(jiān)聽(tīng)器的時(shí)候,可以通過(guò)getAnimatedValue()的方法來(lái)獲取當(dāng)前動(dòng)畫(huà)的值,拿到這個(gè)值后,我們就可以設(shè)置給這個(gè)對(duì)象的在X或者Y軸的偏移量等等,來(lái)讓圖像實(shí)現(xiàn)我們預(yù)定的動(dòng)畫(huà)。
(2)ObjectAnimator
(https://developer.android.com/reference/android/animation/ObjectAnimator.html)
??相比于ValueAnimator,在開(kāi)發(fā)中可能ObjectAnimator要比ValueAnimator用的多,因?yàn)镺bjectAnimator可以直接操作對(duì)象的屬性,而不用像ValueAnimator那么麻煩的設(shè)置監(jiān)聽(tīng)器檢測(cè)值動(dòng)畫(huà)值。
假如讓一個(gè)ImageView做旋轉(zhuǎn)的動(dòng)畫(huà),代碼可以這樣寫(xiě):
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(ivImage,"rotation",0,360);
objectAnimator.setDuration(3000);
objectAnimator.start();
這里第一個(gè)參數(shù)要求傳入一個(gè)object對(duì)象,即進(jìn)行動(dòng)畫(huà)的對(duì)象,在上面我們傳了一個(gè)ImageView。第二個(gè)參數(shù)是屬性的名字,因?yàn)樽鲂D(zhuǎn)動(dòng)畫(huà)所以這里傳的屬性的名字為“rotation”。后面就是可變參數(shù)了,這里我們傳的是0,360,表示讓ImageView旋轉(zhuǎn)360度,然后設(shè)置時(shí)長(zhǎng),調(diào)用start方法
關(guān)于ObjectAnimator類(lèi)這里有很多方法:
ObjectAnimator ofFloat (Object target, String propertyName, float... values)
ObjectAnimator ofInt (T target, Property<T, Integer> xProperty, Property<T, Integer> yProperty, Path path)
ObjectAnimator ofInt (T target, Property<T, Integer> property, int... values)
ObjectAnimator ofInt (Object target, String propertyName, int... values)
ObjectAnimator ofInt (Object target, String xPropertyName, String yPropertyName, Path path)
等等,這里就不做一一講解了.這里我們對(duì)經(jīng)常用到的屬性做一個(gè)小的總結(jié):
①translationX和translationY:表示在X軸或者Y軸方向上的位移
② scaleX和scaleY:表示在X軸或者Y軸方向上的縮放
③rotation、rotationX和rotationY:這三個(gè)屬性控制View對(duì)象圍繞支點(diǎn)進(jìn)行2D和3D旋轉(zhuǎn)。
④ pivotX和pivotY:這兩個(gè)屬性控制著View對(duì)象的支點(diǎn)位置,圍繞這個(gè)支點(diǎn)進(jìn)行旋轉(zhuǎn)和縮放變換處理。默認(rèn)情況下,該支點(diǎn)的位置就是View對(duì)象的中心點(diǎn)。
⑤x和y:這是兩個(gè)簡(jiǎn)單實(shí)用的屬性,它描述了View對(duì)象在它的容器中的最終位置,它是最初的左上角坐標(biāo)和translationX和translationY值的累計(jì)和。
⑥ alpha:它表示View對(duì)象的alpha透明度。默認(rèn)值是1(不透明),0代表完全透明(不可見(jiàn))。