1.Android 動(dòng)畫的工作原理?
十年的秦都網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營銷型網(wǎng)站的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整秦都建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“秦都網(wǎng)站設(shè)計(jì)”,“秦都網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
在android系統(tǒng)中動(dòng)畫分為兩種分別是幀動(dòng)畫和屬性動(dòng)畫。對于動(dòng)畫的工作原理主要涉及到的是幀動(dòng)畫的實(shí)現(xiàn)。
幀動(dòng)畫主要有旋轉(zhuǎn)RotatleAnimation,縮放ScaleAnimation,透明AlphaAnimation,平移TranslateAnimation等都是Animation的子類。Animation控制動(dòng)畫的效果,Transformation 對動(dòng)畫進(jìn)行計(jì)算。
對于動(dòng)畫的原理簡單說就是從一個(gè)動(dòng)畫的啟動(dòng)狀態(tài),到動(dòng)畫結(jié)束狀態(tài),和動(dòng)畫持續(xù)總時(shí)間,在這段時(shí)間中任一時(shí)間點(diǎn)動(dòng)畫的狀態(tài)計(jì)算和顯示的過程。
計(jì)算 :是通過Animation的getTransformation()方法首先對時(shí)間進(jìn)行歸一化時(shí)間讓時(shí)間在0~1之間,進(jìn)行計(jì)算。滿足條件之后就會調(diào)用applyTransformation()方法處理實(shí)現(xiàn)動(dòng)畫類型的計(jì)算。當(dāng)前時(shí)間點(diǎn)的轉(zhuǎn)換狀態(tài)保存到Transformation 的Matrix中等待顯示的時(shí)候使用。
顯示 :動(dòng)畫顯示工作主要依賴于Choreograther類,此類是線程唯一的,Choreograther和Handler用法類似,都是通過post一個(gè)Runnable對象到隊(duì)列中等待VSYSC屏幕垂直同步信號刷新(16ms)刷新一次,然后觸發(fā)ViewRootImpl的view的遍歷工作,回調(diào)到view.draw()方法時(shí)就會把之前applyTransformation 計(jì)算的此時(shí)刻的Transformation 的Matrix賦值到Canvas上, 這也就是為什么我們使用幀動(dòng)畫時(shí)候我們的view的屬性并沒有改變,這就是根源因?yàn)橛?jì)算得到的Matrix被Canvas使用了,并沒有直接賦值到我們的view上。 對于屬性動(dòng)畫來說主要使用animator實(shí)現(xiàn)看下面解析:
2.Animation 和 Animator 的區(qū)別?
Animation和Animator都是抽象類,都有子類,Animation通過Transformation對動(dòng)畫進(jìn)行Matrix轉(zhuǎn)換來作用到Canvas上實(shí)現(xiàn)動(dòng)畫效果。而Animator只是一個(gè)工具類,主要是用來控制在一段時(shí)間內(nèi)某一個(gè)值的變化過程,然后我們再根據(jù)這個(gè)值來作用到view的屬性上,以此來實(shí)現(xiàn)動(dòng)畫效果。為了讓這個(gè)變化的過程能達(dá)到加速減速等變化效果系統(tǒng)提供了插值器Interpolator。他們的實(shí)現(xiàn)思想都是一致的。
3.幀動(dòng)畫 和 屬性動(dòng)畫的區(qū)別?
在 Android 動(dòng)畫中,總共有兩種類型的動(dòng)畫View Animation(視圖動(dòng)畫)和Property Animator(屬性動(dòng)畫);其中
View Animation包括Tween Animation(補(bǔ)間動(dòng)畫)和Frame Animation(逐幀動(dòng)畫);
Property Animator包括ValueAnimator和ObjectAnimation;
首先,直觀上,他們有如下三點(diǎn)不同:
1、引入時(shí)間不同: View Animation是API Level 1就引入的。Property Animation是API Level 11引入的,即Android 3.0才開始有Property Animation相關(guān)的API。
2、所在包名不同: View Animation在包android.view.animation中。而Property Animation API在包 android.animation中。
3、動(dòng)畫類的命名不同: View Animation中動(dòng)畫類取名都叫XXXXAnimation,而在Property Animator中動(dòng)畫類的取名則叫XXXXAnimator大家都知道逐幀動(dòng)畫主要是用來實(shí)現(xiàn)動(dòng)畫的,而補(bǔ)間動(dòng)畫才能實(shí)現(xiàn)控件的漸入漸出、移動(dòng)、旋轉(zhuǎn)和縮放的;而Property Animator是在Android 3.0版本才引入的,之前是沒有的。
為什么還要引入Property Animator呢?
1、為什么引入Property Animator(屬性動(dòng)畫)
我提出一個(gè)假設(shè):請問大家,如何利用補(bǔ)間動(dòng)畫來將一個(gè)控件的背景色在一分鐘內(nèi)從綠色變?yōu)榧t色?這個(gè)效果想必沒辦法僅僅通過改變控件的漸入漸出、移動(dòng)、旋轉(zhuǎn)和縮放來實(shí)現(xiàn)吧,而這個(gè)效果是可以通過Property Animator完美實(shí)現(xiàn)的
**這就是第一個(gè)原因:Property Animator能實(shí)現(xiàn)補(bǔ)間動(dòng)畫無法實(shí)現(xiàn)的功能 **大家都知道,補(bǔ)間動(dòng)畫和逐幀動(dòng)畫統(tǒng)稱為View Animation,也就是說這兩個(gè)動(dòng)畫只能對派生自View的控件實(shí)例起作用;而Property Animator則不同,從名字中可以看出屬性動(dòng)畫,應(yīng)該是作用于控件屬性的!正因?yàn)閷傩詣?dòng)畫能夠只針對控件的某一個(gè)屬性來做動(dòng)畫,所以也就造就了他能單獨(dú)改變控件的某一個(gè)屬性的值!比如顏色!這就是Property Animator能實(shí)現(xiàn)補(bǔ)間動(dòng)畫無法實(shí)現(xiàn)的功能的最重要原因。
**我們得到了第二點(diǎn)不同:View Animation僅能對指定的控件做動(dòng)畫,而Property Animator是通過改變控件某一屬性值來做動(dòng)畫的。
**假設(shè)我們將一個(gè)按鈕從左上角利用補(bǔ)間動(dòng)畫將其移動(dòng)到右下角,在移動(dòng)過程中和移動(dòng)后,這個(gè)按鈕都是不會響應(yīng)點(diǎn)擊事件的。這是為什么呢?因?yàn)檠a(bǔ)間動(dòng)畫僅僅轉(zhuǎn)變的是控件的顯示位置而已,并沒有改變控件本身的值。View Animation的動(dòng)畫實(shí)現(xiàn)是通過其Parent View實(shí)現(xiàn)的,在View被drawn時(shí)Parents View改變它的繪制參數(shù),這樣雖然View的大小或旋轉(zhuǎn)角度等改變了,但View的實(shí)際屬性沒變,所以有效區(qū)域還是應(yīng)用動(dòng)畫之前的區(qū)域;我們看到的效果僅僅是系統(tǒng)作用在按鈕上的顯示效果,利用動(dòng)畫把按鈕從原來的位置移到了右下角,但按鈕內(nèi)部的任何值是沒有變化的,所以按鈕所捕捉的點(diǎn)擊區(qū)域仍是原來的點(diǎn)擊區(qū)域。(下面會舉例來說明這個(gè)問題)
這就得到了第三點(diǎn)不同:補(bǔ)間動(dòng)畫雖能對控件做動(dòng)畫,但并沒有改變控件內(nèi)部的屬性值。而Property Animator則是恰恰相反,Property Animator是通過改變控件內(nèi)部的屬性值來達(dá)到動(dòng)畫效果的
我們前面講了Property Animator包括ValueAnimator和ObjectAnimator;這篇文章就主要來看看ValueAnimator的使用方法吧。
我覺得谷歌那幫老頭是最會起名字的人,單從命名上,就能看出來這個(gè)東東的含義。ValueAnimator從名字可以看出,這個(gè)Animation是針對值的! ValueAnimator不會對控件做任何操作,我們可以給它設(shè)定從哪個(gè)值運(yùn)動(dòng)到哪個(gè)值,通過監(jiān)聽這些值的漸變過程來自己操作控件。 它會自己計(jì)算動(dòng)畫的過程,然后我們需要監(jiān)聽它的動(dòng)畫過程來自己操作控件。
這就是ValueAnimator的功能:ValueAnimator對指定值區(qū)間做動(dòng)畫運(yùn)算,我們通過對運(yùn)算過程做監(jiān)聽來自己操作控件。
總而言之就是兩點(diǎn):
1. ValueAnimator只負(fù)責(zé)對指定的數(shù)字區(qū)間進(jìn)行動(dòng)畫運(yùn)算
2. 我們需要對運(yùn)算過程進(jìn)行監(jiān)聽,然后自己對控件做動(dòng)畫操作
插值器的意義其實(shí)就相當(dāng)于物理公式中的加速度參數(shù),所以這也就是它也叫加速器的原因。 如何自定義插值器:
**input參數(shù)與任何我們設(shè)定的值沒關(guān)系,只與時(shí)間有關(guān),隨著時(shí)間的增長,動(dòng)畫的進(jìn)度也自然的增加,input參數(shù)就代表了當(dāng)前動(dòng)畫的進(jìn)度。而返回值則表示動(dòng)畫的當(dāng)前數(shù)值進(jìn)度 **
在getInterpolation函數(shù)中,我們將進(jìn)度反轉(zhuǎn)過來,當(dāng)傳0的時(shí)候,我們讓它數(shù)值進(jìn)度在完成的位置,當(dāng)完成的時(shí)候,我們讓它在開始的位置
ObjectAnimator是派生自ValueAnimator的,所以ValueAnimator中所能使用的方法,在ObjectAnimator中都可以正常使用。ObjectAnimator重寫了幾個(gè)方法,比如ofInt(),ofFloat()等。利用ObjectAnimator重寫的ofFloat方法如何實(shí)現(xiàn)一個(gè)動(dòng)畫:(改變透明度)
前面我們都是定義多個(gè)值,即至少兩個(gè)值之間的變化,那如果我們只定義一個(gè)值呢,如下面的方式:(同樣以MyPointView為例)
僅且僅當(dāng)我們只給動(dòng)畫設(shè)置一個(gè)值時(shí),程序才會調(diào)用屬性對應(yīng)的get函數(shù)來得到動(dòng)畫初始值。如果動(dòng)畫沒有初始值,那么就會使用系統(tǒng)默認(rèn)值。比如ofInt()中使用的參數(shù)類型是int類型的,而系統(tǒng)的Int值的默認(rèn)值是0,所以動(dòng)畫就會從0運(yùn)動(dòng)到100;也就是系統(tǒng)雖然在找到不到屬性對應(yīng)的get函數(shù)時(shí),會給出警告,但同時(shí)會用系統(tǒng)默認(rèn)值做為動(dòng)畫初始值。
如果通過給自定義控件MyPointView設(shè)置了get函數(shù),那么將會以get函數(shù)的返回值做為初始值。
根據(jù) View setBackGroundColor() 方法可以自定義條用屬性動(dòng)畫。
通過AnimationListener可以監(jiān)聽Animation的運(yùn)行過程,有三個(gè)方法分別是Animation開始的時(shí)候調(diào)用,完成的時(shí)候調(diào)用,重復(fù)的時(shí)候調(diào)用。
AnimationSet,動(dòng)畫集合。 我們最常用的是調(diào)用其 addAnimation 將一個(gè)個(gè)不一樣的動(dòng)畫組織到一起來,然后調(diào)用view 的 startAnimation 方法觸發(fā)這些動(dòng)畫執(zhí)行。
setAnimation是告訴該控件我待會要執(zhí)行什么動(dòng)畫,而要執(zhí)行的的動(dòng)畫,是需要手動(dòng)添加的。并且需要父view在動(dòng)畫快要開啟的時(shí)候,調(diào)用invalidate。需要一定的條件限制。
而startAnimation告訴該控件,我要立馬執(zhí)行該動(dòng)畫,該動(dòng)畫就是已經(jīng)設(shè)置好的動(dòng)畫。調(diào)用它時(shí)就會立即開始動(dòng)畫。
參看這篇文章: Android動(dòng)畫之Interpolator插補(bǔ)器和TypeEvaluator估值器
Property Animation提供了Animator.AnimatorListener和Animator.AnimatorUpdateListener兩個(gè)監(jiān)聽器用于動(dòng)畫在播放過程中的重要?jiǎng)赢嬍录O旅媸莾蓚€(gè)監(jiān)聽器接口和方法的一些介紹和說明:
上面講到ViewAnimation有許多xml加載,當(dāng)然PropertyAnimation也可以對應(yīng)xml加載,位置為 res/animator/
animator.xml
調(diào)用就用到了AnimatorInflater類了
組合動(dòng)畫也可以xml加載
在 Android 3.0 中給 View 增加了一些新的屬性以及相應(yīng)的 getter、setter 方法。Property Animation系統(tǒng)可以通過修改 View 對象實(shí)際的屬性值來實(shí)現(xiàn)屏幕上的動(dòng)畫效果。此外,當(dāng)屬性值發(fā)生變化時(shí),Views 也會自動(dòng)調(diào)用 invalidate() 方法來刷新屏幕。 View 類中新增的便于實(shí)現(xiàn) property 動(dòng)畫的屬性包括:
1 . 第一個(gè)參數(shù):設(shè)置目標(biāo)對象,即操縱的view
2 . 第二個(gè)參數(shù):設(shè)置操作的動(dòng)畫的屬性值(見上面講解的動(dòng)畫屬性值)
3 . 第三個(gè)參數(shù):可變數(shù)組參數(shù) (初始值,中間值,結(jié)束值)??梢杂幸粋€(gè)到N個(gè),如果是一個(gè)值的話默認(rèn)這個(gè)值是動(dòng)畫過渡值的結(jié)束值。如果有N個(gè)值,動(dòng)畫就在這N個(gè)值之間過渡。
針對同一個(gè)對象多個(gè)屬性,同時(shí)作用多種動(dòng)畫
可以調(diào)用其playTogether(同時(shí)執(zhí)行)、playSequentially(順序執(zhí)行)、play、before、with、after 等方法設(shè)置動(dòng)畫的執(zhí)行順序,然后調(diào)用其start 觸發(fā)動(dòng)畫執(zhí)行。
Android 3.0后,谷歌給View增加animate方法直接驅(qū)動(dòng)屬性動(dòng)畫。
??android中酷炫的效果,都離不開動(dòng)畫的支持。這里我們詳細(xì)介紹一下android中動(dòng)畫的分類。android的中動(dòng)畫分為幀動(dòng)畫、補(bǔ)間動(dòng)畫、屬性動(dòng)畫。原理各不相同,實(shí)現(xiàn)的效果也大不相同。下面一一講解三種動(dòng)畫。
??幀動(dòng)畫顧名思義就是通過順序一幀一幀播放圖片從而產(chǎn)生動(dòng)畫效果,效果類似放電影。該動(dòng)畫缺點(diǎn)比較明顯,就是如果圖片過大過多會導(dǎo)致OOM。幀動(dòng)畫xml文件放置在drawable目錄下而非anim文件夾下。
??補(bǔ)間動(dòng)畫是通過對view進(jìn)行旋轉(zhuǎn)、縮放、漸變、透明度變化,而達(dá)到的一種動(dòng)畫效果。是一種漸進(jìn)式動(dòng)畫。并且可以通過組合以上四種操作,完成復(fù)雜的自定義動(dòng)畫效果。缺點(diǎn)就是只是改變的view的展示狀態(tài),但是不會改變view的位置。例如我們將一個(gè)button通過位移想左移動(dòng)100dp,然后停留在終點(diǎn)。但是我們可以發(fā)現(xiàn)展示的位置button點(diǎn)擊無效果,不可以交互。而在button原始位置空白的地方點(diǎn)擊會觸發(fā)button的點(diǎn)擊效果。也就是button本質(zhì)還是在原來位置,只是展示左移了100dp。
透明度動(dòng)畫,通過改變view的透明度展示動(dòng)畫。對應(yīng)AlphaAnimation和alphaxml標(biāo)簽
縮放動(dòng)畫,通過修改view的大小展示動(dòng)畫。對應(yīng)ScaleAnimation類和scalexml表情
通過旋轉(zhuǎn)view展示動(dòng)畫。對應(yīng)RotateAnimation類和rotatexml標(biāo)簽
平移動(dòng)畫,更改view的展示位置展示動(dòng)畫。對應(yīng)TranslateAnimation類和translatexml表情
應(yīng)用動(dòng)畫xml配置
使用java類配置動(dòng)畫,具體參數(shù)類同xml參數(shù),建議使用xml配置動(dòng)畫
??屬性動(dòng)畫本質(zhì)是通過改變對象的屬性(例如:x,y等屬性),來實(shí)現(xiàn)動(dòng)畫的,所以基本上是無所不能的,只要對象有這個(gè)屬性,就能實(shí)現(xiàn)動(dòng)畫效果。屬性動(dòng)畫是在api11的新特性,通過動(dòng)態(tài)的改變view的屬性從而達(dá)到動(dòng)畫效果。雖然可以使用nineoldandroid庫向下兼容,但是兼容本質(zhì)是使用補(bǔ)間動(dòng)畫完成,也就是說不會更改view的屬性,也不會更改view的位置。屬性動(dòng)畫比較常用的類: ValueAnimator、ObjectAnimator、AnimationSet,其中ObjectAnimator是ValueAnimator的子類,而AnminationSet是動(dòng)畫集合
動(dòng)畫配置同樣可以使用xml配置,參數(shù)類似,這里不做詳細(xì)說明。
根據(jù)時(shí)間流逝百分比計(jì)算當(dāng)前屬性改變百分比。同xml配置動(dòng)畫中的 android:interpolator 屬性配置,常見有LinearInterpolator(線性差值器)、AccelerateDecelerateInterpolator(加速減速差值器)
等。自定義需要實(shí)現(xiàn) Interpolator 或者 TimeInterpolator 。Interpolator接口繼承TimeInterpolator。
根據(jù)當(dāng)前屬性改變百分比計(jì)算改變后的屬性值。屬性動(dòng)畫特有的屬性。自定義估值器需要實(shí)現(xiàn) TypeEvaluator 接口。
可以對任意屬性做屬性動(dòng)畫,屬性動(dòng)畫要求動(dòng)畫作用的對象提供該屬性的get()和set()方法。因?yàn)閷傩詣?dòng)畫本質(zhì)就是根據(jù)外界傳遞的對象屬性的初始值和終點(diǎn)值,然后根據(jù)估值器和差值器計(jì)算屬性值,不斷調(diào)用屬性的set方法,通過時(shí)間的推移所傳遞的值,越來越近終點(diǎn)值。
注意:
使用ValueAnimator通過監(jiān)聽動(dòng)畫過程,自己改變對象屬性完成動(dòng)畫