Android開(kāi)發(fā)藝術(shù)探索學(xué)習(xí)筆記(七)
第七章 Android動(dòng)畫深入分析
Android的動(dòng)畫分為三種:View動(dòng)畫,幀動(dòng)畫,屬性動(dòng)畫。幀動(dòng)畫屬于View動(dòng)畫。
7.1 View動(dòng)畫
View動(dòng)畫的作用對(duì)象是View,共有四種動(dòng)畫效果:平移(Translate),縮放(Scale),旋轉(zhuǎn)(Rotate),透明度(Alpha)。
7.1.1 View動(dòng)畫的種類
View動(dòng)畫的保存路徑:res/anim/filename.xml。XML格式語(yǔ)法如下:
<?xml version="1.0" encoding="utf-8" ?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@anim/interpolator_resource" android:shareInterpolator="true|false"> <alpha android:fromAlpha="float"<!-- 透明度起始值--> android:toAlpha="float"/><!-- 透明度結(jié)束值--> <scale android:fromXScale="float"<!--水平方向縮放起始值 --> android:toXScale="float"<!--水平方向縮放結(jié)束值 --> android:fromYScale="float"<!--垂直方向縮放起始值 --> android:toYScale="float"<!--垂直方向縮放結(jié)束值 --> android:pivotX="float"<!--縮放軸點(diǎn)x坐標(biāo) --> android:pivotY="float"/><!--縮放軸點(diǎn)y坐標(biāo) --> <translate android:fromXDelta="float"<!--x的起始位置--> android:fromYDelta="float"<!--y的起始位置--> android:toXDelta="float"<!--x的結(jié)束位置--> android:toYDelta="float"/><!--y的結(jié)束位置--> <rotate android:fromDegrees="float"<!--起始角度 --> android:toDegrees="float"<!-- 結(jié)束角度--> android:pivotX="float"<!-- 旋轉(zhuǎn)軸點(diǎn)x坐標(biāo) --> android:pivotY="float"/><!-- 旋轉(zhuǎn)軸點(diǎn)y坐標(biāo)--> <set> ... </set> </set>
<set>標(biāo)簽表示動(dòng)畫集合,對(duì)應(yīng)AnimationSet類,內(nèi)部還可以嵌套其他動(dòng)畫集合。
android:interpolator 插值器規(guī)定動(dòng)畫已怎樣的速度運(yùn)行,默認(rèn)為加速減速插值器。
android:shareInterpolator 集合中的動(dòng)畫是否和集合共享同一個(gè)插值器。
android:duration 動(dòng)畫持續(xù)時(shí)間
android:fillAfter 動(dòng)畫結(jié)束后View是否停留在結(jié)束位置。
<scale>、<rotate>中軸點(diǎn)默認(rèn)情況下是View的中心點(diǎn)(有待驗(yàn)證貌似是左上角)。
在代碼中加載xml中定義的動(dòng)畫:
Animation animation = AnimationUtils.loadAnimation(this, R.anim.view1); button.startAnimation(animation);
使用Animation的setAnimationListener方法可以給View動(dòng)畫添加監(jiān)聽(tīng)。
7.1.2 自定義View動(dòng)畫
原理:繼承Animation這個(gè)抽象類,然后重寫它的initialize和applyTransformation方法,在initialize中做初始化,在applyTransformation中進(jìn)行相應(yīng)的矩陣變換即可。通常采用camera來(lái)簡(jiǎn)化矩陣變換的過(guò)程。自定義View動(dòng)畫的過(guò)程主要就是矩陣變換的過(guò)程。例子可參考APIDEMO中的Rotate3dAnimation效果。
7.1.3 幀動(dòng)畫
幀動(dòng)畫其實(shí)就是順序播放一組預(yù)先定義好的圖片。通過(guò)AnimationDrawable來(lái)使用幀動(dòng)畫。XML格式語(yǔ)法如下:
<?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="@mipmap/ic_launcher" android:duration="500"/> <item android:drawable="@mipmap/ic_launcher" android:duration="500"/> <item android:drawable="@mipmap/ic_launcher" android:duration="500"/> </animation-list>
使用時(shí)直接作為View的背景并通過(guò)Drawable來(lái)播放即可。
button.setBackgroundResource(R.drawable.view2); AnimationDrawable drawable=(AnimationDrawable)button.getBackground(); drawable.start();
7.2 View動(dòng)畫的特殊使用場(chǎng)景
7.2.1 LayoutAnimation
作用于ViewGroup,為ViewGroup指定一個(gè)動(dòng)畫,這樣當(dāng)它的子元素出場(chǎng)時(shí)都會(huì)具有這種動(dòng)畫效果。
步驟:
(1)定義LayoutAnimation
<?xml version="1.0" encoding="utf-8" ?> <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:delay="0.5" android:animationOrder="normal" android:animation="@anim/anim_item"/>
android:delay 子元素開(kāi)始動(dòng)畫的時(shí)間延遲,例如子元素設(shè)置duration為200ms,則0.5表示每個(gè)子元素都需要延遲100ms開(kāi)能開(kāi)始播放動(dòng)畫,即第一個(gè)經(jīng)過(guò)100ms開(kāi)始播放,第二個(gè)就得經(jīng)過(guò)200ms開(kāi)始播放,第三個(gè)就得經(jīng)過(guò)300ms開(kāi)始播放,以此類推。
android:animationOrder 子元素動(dòng)畫順序,normal(順序顯示),reverse(逆向顯示),random(隨機(jī))。
(2)為子元素指定動(dòng)畫
<?xml version="1.0" encoding="utf-8" ?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300" android:interpolator="@android:anim/accelerate_interpolator" android:shareInterpolator="true"> <alpha android:fromAlpha="0.0" android:toAlpha="1.0" /> <translate android:fromXDelta="500" android:toYDelta="0" /> </set>
(3)為ViewGroup指定android:layoutAnimation屬性
android:layoutAnimation="@anim/anim_layout"
或者通過(guò)LayoutAnimationController來(lái)為ViewGroup指定動(dòng)畫。
Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_item); LayoutAnimationController controller=new LayoutAnimationController(animation); controller.setDelay(0.5f); controller.setOrder(LayoutAnimationController.ORDER_NORMAL); linearlayout.setLayoutAnimation(controller);
7.2.2 Activity的切換效果
使用overridePendingTransition(int enterAnim, int exitAnim)方法,注意這個(gè)方法必須在startActivity或者finish之后被調(diào)用才能生效。
enterAnim——Activity被打開(kāi)時(shí)的動(dòng)畫
exitAnim——Activity退出時(shí)的動(dòng)畫
啟動(dòng)Activity:
Intent intent =new Intent(this,TestActivity.class); startActivity(intent); overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
退出Activity:
@Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
}
7.3 屬性動(dòng)畫
API等級(jí)必須大于等于11,存放路徑為res/animator/目錄下,屬性動(dòng)畫可以對(duì)任何對(duì)象做動(dòng)畫,常見(jiàn)的有ValueAnimator、ObjectAnimator。
7.3.1 使用屬性動(dòng)畫
屬性動(dòng)畫默認(rèn)時(shí)間間隔為300ms,默認(rèn)幀率為10ms/幀,可以達(dá)到在一個(gè)時(shí)間間隔內(nèi)完成對(duì)象從一個(gè)屬性值到另一個(gè)屬性值的改變。如果想要屬性動(dòng)畫兼容低版本系統(tǒng),需要使用NineOldAndroids這個(gè)開(kāi)源動(dòng)畫庫(kù)。
舉例說(shuō)明如何使用屬性動(dòng)畫:
(1)改變一個(gè)對(duì)象的translationY屬性,讓其沿著Y軸向上平移一段距離:它的高度。
ObjectAnimator.ofFloat(myObject,"translationY",-myObject.getHeight());
(2)改變一個(gè)View的背景色,讓其背景色在3秒內(nèi)實(shí)現(xiàn)用0xFFFF8080到0xFF8080FF的漸變,動(dòng)畫無(wú)限循環(huán)并加反轉(zhuǎn)效果。
ValueAnimator colorAnim=ObjectAnimator.ofInt(this,"backgroundColor",0xFFFF8080,0xFF8080FF); colorAnim.setDuration(3000); colorAnim.setEvaluator(new ArgbEvaluator()); colorAnim.setRepeatCount(ValueAnimator.INFINITE); colorAnim.setRepeatMode(ValueAnimator.REVERSE); colorAnim.start();
屬性動(dòng)畫的XML格式語(yǔ)法如下:
<?xml version="1.0" encoding="utf-8" ?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially|together"><!--together:子動(dòng)畫同時(shí)播放。sequentially:自動(dòng)化按照先后順序依次播放--> <objectAnimator android:duration="int"<!--動(dòng)畫時(shí)長(zhǎng)--> android:propertyName="string"<!--屬性名稱--> android:repeatCount="int"<!--重復(fù)次數(shù)--> android:repeatMode="restart|reverse"<!--重復(fù)模式--> android:startOffset="int"<!--延遲時(shí)間--> android:valueFrom="float|int|color"<!--屬性起始值--> android:valueTo="float|int|color"<!--屬性結(jié)束值--> android:valueType="colorType|intType|floatType|pathType" /><!--屬性類型--> <animator android:duration="int" android:repeatCount="int" android:repeatMode="restart|reverse" android:startOffset="int" android:valueFrom="float|int|color" android:valueTo="float|int|color" android:valueType="colorType|intType|floatType|pathType" /> </set>
android:repeatCount 動(dòng)畫的循環(huán)次數(shù),默認(rèn)為0,-1為無(wú)限循環(huán);
android:repeatMode repeat:連續(xù)重復(fù);reverse:逆向重復(fù)(第一次播放完后,第二次倒著播放,第三次在重頭開(kāi)始播如此反復(fù))。
在XML中定義好屬性動(dòng)畫后在java代碼中就可以使用了
AnimatorSet set=(AnimatorSet) AnimatorInflater.loadAnimator(context,R.anim.property_animator); set.setTarget(button); set.start();
實(shí)際開(kāi)發(fā)中建議使用代碼來(lái)實(shí)現(xiàn)屬性動(dòng)畫,不要使用xml的方式。
7.3.2 理解插值器和估值器
插值器:根據(jù)時(shí)間流逝的百分比來(lái)計(jì)算出當(dāng)前屬性值改變的百分比;
估值器:根據(jù)當(dāng)前屬性的百分比來(lái)計(jì)算改變后的屬性值。
7.3.3 屬性動(dòng)畫監(jiān)聽(tīng)器
AnimatorListener監(jiān)聽(tīng)動(dòng)畫的開(kāi)始、結(jié)束、取消、重復(fù)播放;
AnimatorUpdateListener 監(jiān)聽(tīng)整個(gè)動(dòng)畫過(guò)程。
7.3.4 對(duì)任意屬性做動(dòng)畫
對(duì)object的屬性abc做動(dòng)畫,如果想讓動(dòng)畫生效需要滿足一下兩個(gè)條件:
(1)object必須要提供setAbc方法,如果動(dòng)畫的時(shí)候沒(méi)有傳遞初始值,那么還得提供getAbc方法,否則程序直接crash;
(2)object的setAbc對(duì)屬性abc所做的改變必須能夠通過(guò)某種方法反映出來(lái),比如帶來(lái)UI的改變。
如何給一個(gè)原始對(duì)象添加動(dòng)畫可參見(jiàn)p285頁(yè)的方法2;
7.3.5 屬性動(dòng)畫的工作原理
屬性動(dòng)畫要求動(dòng)畫作用的對(duì)象提供該屬性的set方法,屬性動(dòng)畫根據(jù)你傳遞的該屬性的初始值和最終值,以及動(dòng)畫的效果多次去掉用set方法。每次 傳遞給set方法的值都是不一樣的,確切來(lái)說(shuō)是隨著時(shí)間的推移,所傳遞的值越來(lái)越接近最終值。如果動(dòng)畫的時(shí)候沒(méi)有傳遞初始值,那么還要提供get方法,因 為系統(tǒng)要去獲取屬性的初始值。
7.4 使用動(dòng)畫的注意事項(xiàng)
注 意View動(dòng)畫是對(duì)View的影像做動(dòng)畫,并不是真正改變View的狀態(tài),因此有時(shí)候會(huì)出現(xiàn)動(dòng)畫完成后View無(wú)法隱藏的現(xiàn)象,即 setVisibility(View.GONE)失效了,這個(gè)時(shí)候只要調(diào)用view.clearAnimation()清除View動(dòng)畫即可解決此問(wèn) 題。
將View移動(dòng)(平移)后,在Android3.0以前的系統(tǒng)上,不管是View動(dòng)畫還是屬性動(dòng)畫,新位置均無(wú)法觸發(fā)單擊事件,同時(shí),老位置仍 然可以觸發(fā)單擊事件。盡管View已經(jīng)在視覺(jué)上不存在了,將View移回原位置以后,原位置的單擊事件繼續(xù)生效。從3.0開(kāi)始,屬性動(dòng)畫的單擊事件觸發(fā)位 置為移動(dòng)后的位置,但是View動(dòng)畫仍然在原位置。
關(guān)于Android開(kāi)發(fā)藝術(shù)探索學(xué)習(xí)筆記(七)就給大家介紹這么多,后續(xù)還會(huì)持續(xù)更新android藝術(shù)探索相關(guān)知識(shí),請(qǐng)大家持續(xù)關(guān)注本站,謝謝。
相關(guān)文章
android實(shí)現(xiàn)節(jié)點(diǎn)進(jìn)度條效果
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)節(jié)點(diǎn)進(jìn)度條效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Android實(shí)現(xiàn)取消GridView中Item選中時(shí)默認(rèn)的背景色
這篇文章主要介紹了Android實(shí)現(xiàn)取消GridView中Item選中時(shí)默認(rèn)的背景色,涉及Android GridView中Item屬性設(shè)置的相關(guān)技巧,需要的朋友可以參考下2016-02-02
安裝時(shí)加入外部數(shù)據(jù)庫(kù)示例(android外部數(shù)據(jù)庫(kù))
這篇文章主要介紹了android打包安裝時(shí)加入外部數(shù)據(jù)庫(kù)的示例,需要的朋友可以參考下2014-03-03
Activity實(shí)例詳解之啟動(dòng)activity并返回結(jié)果
這篇文章主要介紹了Activity實(shí)例詳解之啟動(dòng)activity并返回結(jié)果 的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09
解決NDK開(kāi)發(fā)中Eclipse報(bào)錯(cuò)Unresolved inclusion jni.h的最終解決方法(已測(cè))
這篇文章主要介紹了解決NDK開(kāi)發(fā)中Eclipse報(bào)錯(cuò)Unresolved inclusion jni.h的最終方法,需要的朋友可以參考下2016-12-12
深入理解與運(yùn)行Android Jetpack組件之ViewModel
ViewModel是Android Jetpack組件之一,是一種用于管理UI相關(guān)數(shù)據(jù)的架構(gòu)組件,它能夠幫助開(kāi)發(fā)者實(shí)現(xiàn)優(yōu)雅的數(shù)據(jù)驅(qū)動(dòng)和生命周期管理,本文將深入淺出地介紹ViewModel的使用和原理,帶你一步步掌握這個(gè)強(qiáng)大的組件2023-08-08
Android Studio連接手機(jī)設(shè)備教程
這篇文章主要為大家詳細(xì)介紹了Android Studio連接手機(jī)設(shè)備教程,非常完整的連接步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Android讀取properties配置文件的實(shí)例詳解
這篇文章主要介紹了Android讀取properties配置文件的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09

