Android中的動(dòng)畫(huà)概述

動(dòng)畫(huà)可以分為三類(lèi):View動(dòng)畫(huà),幀動(dòng)畫(huà),屬性動(dòng)畫(huà)。

一、View動(dòng)畫(huà)

1.View動(dòng)畫(huà)包括四種:平移動(dòng)畫(huà),縮放動(dòng)畫(huà),旋轉(zhuǎn)動(dòng)畫(huà),透明度動(dòng)畫(huà)。分別對(duì)應(yīng)著Animation的四個(gè)子類(lèi):TranslateAnimation,ScaleAnimation,RotateAnimation,AlphaAnimation。幀動(dòng)畫(huà)其實(shí)也是View動(dòng)畫(huà)的一種。

2.View動(dòng)畫(huà)是對(duì)View的影像做動(dòng)畫(huà),并不是真正的改變View的位置等狀態(tài)。通過(guò)View動(dòng)畫(huà)將View平移后,新位置不能觸發(fā)點(diǎn)擊事件,老位置可以。

3.使用View動(dòng)畫(huà),在動(dòng)畫(huà)完成后,有時(shí)候會(huì)出現(xiàn)View無(wú)法隱藏的現(xiàn)象,即設(shè)置setVisiable(View.GONE)沒(méi)有效果,這個(gè)時(shí)候只需要調(diào)用view.clearAnimation()清除View動(dòng)畫(huà)即可解決此問(wèn)題。

4.View動(dòng)畫(huà)的使用:

通過(guò)XMl定義:Animation animation = AnimationUtils.loadAnimation(context,resId);

view.startAnimation(animation);

通過(guò)純代碼:

AlphaAnimation alphaAnimation = new AlphaAnimation(0,1);

alphaAnimation.setDuration(300);

view.startAnimation(alphaAnimation);

為動(dòng)畫(huà)設(shè)置監(jiān)聽(tīng):

animation.setAnimationListener(new Animation.AnimationListener());

5.自定義View動(dòng)畫(huà):

繼承Animation類(lèi),重寫(xiě)initialize和applyTransformation方法,在initialize方法中做一些初始化工作,在applyTransformation中進(jìn)行相應(yīng)的矩陣變換。很多時(shí)候需要用到Camera來(lái)簡(jiǎn)化矩陣變換的過(guò)程,需要用到數(shù)學(xué)上面的東西。實(shí)際開(kāi)發(fā)中很少用到自定義View動(dòng)畫(huà)。

二、幀動(dòng)畫(huà)

1.幀動(dòng)畫(huà)是順序播放一組預(yù)先定義好的圖片,類(lèi)似于電影播放。對(duì)應(yīng)于AnimationDrawable類(lèi)。

XML中的定義方式如下(在drawable文件夾中):

然后將上訴Drawable作為View的背景并通過(guò)AnimationDrawable來(lái)播放:

view.setBackgroundResource(R.drawable.resid);

AnimationDrawable drawable = view.getBackground();

drawable.start();

2.幀動(dòng)畫(huà)使用比較簡(jiǎn)單,但是比較容易引起OOM,所以在使用幀動(dòng)畫(huà)時(shí)應(yīng)盡量避免使用過(guò)多尺寸較大的圖片。

3.View動(dòng)畫(huà)的一個(gè)特殊使用場(chǎng)景,就是為ViewGroup中的所有子元素添加出場(chǎng)效果,需要用到LayoutAnimation。

定義LayoutAnimation:

android:delay="0.5"

android:animationOrder="normal"

android:animation="@anim/anim_item">

其中anim_item就是具體的View動(dòng)畫(huà),然后為ViewGroup指定android:layoutAnimation屬性 android:layoutAnimation=“@anim/layout_animation”;

4.除了在XML中指定LayoutAnimation外,還可以通過(guò)LayoutAnimationController來(lái)實(shí)現(xiàn):

Animation animation = AnimationUtils.loadAnimation(context,resid);

LayoutAnimationController controller = new LayoutAnimationController(animation);

controller.setDelay(0.5f);

controller.setOrder(LayoutAnimationController.ORDER_NORMAL);

viewGroup.setLayoutAnimation(controller);

5.Activity的切換效果:

調(diào)用overridePendingTransition(resid,resid),但是必須在startActivity跟finish之后調(diào)用才有效果!

三、屬性動(dòng)畫(huà)

1.屬性動(dòng)畫(huà)是API 11(3.1) 新加入的特性,和View動(dòng)畫(huà)不同,它對(duì)作用對(duì)象進(jìn)行了擴(kuò)展,屬性動(dòng)畫(huà)可以對(duì)任何對(duì)象做動(dòng)畫(huà),甚至還可以沒(méi)有對(duì)象。

動(dòng)畫(huà)默認(rèn)時(shí)間間隔300ms,默認(rèn)幀率10ms/幀。其可以達(dá)到的效果是:在一個(gè)時(shí)間間隔內(nèi)完成對(duì)象從一個(gè)屬性值到另一個(gè)屬性值的改變。

2.比較常用的幾個(gè)動(dòng)畫(huà)類(lèi):ValueAnimator,ObjectAnimator,AnimatorSet。其中ObjectAnimator繼承自ValueAnimator,AnimatorSet和ValueAnimator都繼承自Animator。

AnimatorSet是個(gè)動(dòng)畫(huà)集合,可以定義一組動(dòng)畫(huà)。

3.Animator是個(gè)抽象類(lèi),實(shí)現(xiàn)了Cloneable接口,Cloneable接口里面什么都沒(méi)有。

4.ValueAnimator不能對(duì)具體的某個(gè)屬性做動(dòng)畫(huà),但是可以對(duì)一個(gè)值做動(dòng)畫(huà),就是實(shí)現(xiàn)值的漸變。例如:ValueAnimator.ofInt(1.100)。具體的對(duì)某個(gè)屬性值的動(dòng)畫(huà)的實(shí)現(xiàn),在它的子類(lèi)ObjectAnimator中。不過(guò)可以通過(guò)ValueAnimator對(duì)值的漸變,結(jié)合AnimatorUpdateListener可以做很多事情(包括實(shí)現(xiàn)屬性動(dòng)畫(huà))。

5.使用方法示例:

通過(guò)代碼:ObjectAnimator.ofFloat(view,"propertyName",value).start();

通過(guò)XML:屬性動(dòng)畫(huà)需要定義在res/animator/目錄下面,語(yǔ)法如下:

android:ordering="together">

android:propertyName="x"

android:duration="300"

android:valueTo="200"

android:valueType="floatType"/>

android:propertyName="y"

android:duration="300"

android:valueTo="300"

android:valueType="floatType"/>

一個(gè)下面可以包含多個(gè)。

AnimatorSet set = AnimatorSet.loadAnimator(context,resid);

set.setTarget(view);

set.start();

6.插值器與估值器

插值器:根據(jù)時(shí)間流逝的百分比來(lái)計(jì)算出當(dāng)前屬性值改變的百分比。TimeInterpolator

系統(tǒng)預(yù)置的有LinearInterpolator(線性插值器:勻速動(dòng)畫(huà))、AccelerateDecelerateInterpolator(加速減速插值器:動(dòng)畫(huà)兩頭慢,中間快)、DecelerateInterpolator(減速插值器:動(dòng)畫(huà)越來(lái)越慢)等。

這些插值器都繼承自BaseInterpolator,BaseInterpolator實(shí)現(xiàn)了Interpolator接口,而Interpolator幾口繼承自TimeInterpolator接口。TimeInterpolator接口定義一個(gè)方法叫:

public float getInterpolation(float intput); 所以自定義插值器的話,只需要實(shí)現(xiàn)Interpolator或者TimeInterpolator接口。

估值器:根據(jù)當(dāng)前屬性改變的百分比來(lái)計(jì)算改變后的屬性值。TypeEvaluator

系統(tǒng)預(yù)置的估值器有IntEvaluator(針對(duì)整型屬性)、FloatEvaluator(針對(duì)浮點(diǎn)型)、ArgbEvaluator(針對(duì)Color屬性)。

它們都實(shí)現(xiàn)了TypeEvaluator接口,TypeEvaluator接口中定義了一個(gè)方法:

public T evaluate(float fraction, T startValue, T endValue);

7.屬性動(dòng)畫(huà)要求對(duì)象的該屬性必須有set方法,get方法可選(如果提供了動(dòng)畫(huà)的初始值,則不需要get方法,若沒(méi)有提供初始值,那么系統(tǒng)會(huì)調(diào)用get方法獲取初始值)。

8.對(duì)任意屬性做動(dòng)畫(huà):如果對(duì)象沒(méi)有該屬性的set或者get方法,可以通過(guò)如下3種方式解決:

①:給對(duì)象加上get和set方法,如果有權(quán)限的話。

②:用一個(gè)類(lèi)來(lái)包裝原始對(duì)象,間接為其提供get,set方法。(此方法比較常用)

③:采用ValueAnimator,監(jiān)聽(tīng)動(dòng)畫(huà)過(guò)程,自己實(shí)現(xiàn)屬性的改變。

關(guān)于方法2的例子:

例如如果對(duì)Button的width屬性做動(dòng)畫(huà),但是Button的width的set方法是設(shè)置最大跟最小寬度,而不是改變其寬度。get方法是獲取寬度。這樣的話直接對(duì)width屬性做動(dòng)畫(huà)是沒(méi)有效果的,因?yàn)楦静皇窃O(shè)置的那個(gè)我們想改變的寬度。這樣我們可以通過(guò)一個(gè)類(lèi)去包裝Button,然后在這個(gè)類(lèi)的setWidth方法中,去

button.getLayoutParams().width = width.

button.requestLayout();

這樣就間接的給Button的寬度做了動(dòng)畫(huà)。因?yàn)橹苯訛檫@個(gè)寬度去加set方法是行不通的,Button封裝在SDK中,我們改變不了。

9.在動(dòng)畫(huà)的內(nèi)部,get,set方法的調(diào)用是通過(guò)反射來(lái)實(shí)現(xiàn)的。

注意:屬性動(dòng)畫(huà)必須運(yùn)行在有Looper的線程中,否則會(huì)拋出“Animators may only be run on Looper threads”異常。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 1 背景 不能只分析源碼呀,分析的同時(shí)也要整理歸納基礎(chǔ)知識(shí),剛好有人微博私信讓全面說(shuō)說(shuō)Android的動(dòng)畫(huà),所以今...
    未聞椛洺閱讀 2,746評(píng)論 0 10
  • 概述 在Android開(kāi)發(fā)的過(guò)程中,View的變化是很常見(jiàn)的,如果View變化的過(guò)程沒(méi)有動(dòng)畫(huà)來(lái)過(guò)渡而是瞬間完成,會(huì)...
    小蕓論閱讀 39,053評(píng)論 18 134
  • Animation Animation類(lèi)是所有動(dòng)畫(huà)(scale、alpha、translate、rotate)的基...
    四月一號(hào)閱讀 1,936評(píng)論 0 10
  • 將薄毯蓋好 手腳放好 將冷氣赫茲調(diào)好 窗簾對(duì)齊邊角擺好 暗房里沒(méi)有相片 鏡頭收好 急著刷分貝的馬達(dá) 沖向救護(hù)室的擔(dān)...
    Oran閱讀 187評(píng)論 0 0
  • 漸漸有了自己的想法說(shuō)起孤獨(dú),可謂生命的常態(tài)吧。 小時(shí)候,天真無(wú)邪,以為所能看到的天空就是整個(gè)世界。 隨著歲月的洗禮...
    波斯女神閱讀 181評(píng)論 0 1