Android—逐帧、补间、属性动画
1、Tween Animation 補(bǔ)間動(dòng)畫
? ? ? 這類動(dòng)畫比較簡單,一般就是平移、縮放、旋轉(zhuǎn)、透明度,或者其組合,可以用代碼或者xml文件的形式,推薦使用xml文件形式,因?yàn)榭梢詮?fù)用。
? ? ? 四個(gè)動(dòng)畫效果實(shí)現(xiàn)類:TranslateAnimation、ScaleAnimation、RotateAnimation、AlphaAnimation、AnimationSet,對(duì)應(yīng)的的XML標(biāo)簽為translate、 scale、 rotate、alpha、set,其中set里還可以放set,然后放在放置在res/anim/目錄下,關(guān)于詳細(xì)使用這里不再做介紹。
1.alpha漸變透明度動(dòng)畫效果
<?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android="http://schemas.android.com/apk/res/android"android:duration="500" //動(dòng)畫持續(xù)時(shí)間 android:fromAlpha="1.0" //透明度變化android:toAlpha="0.0" />2.scale漸變尺寸縮放動(dòng)畫效果
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android"android:duration="500"android:fromXScale="0.0" // 動(dòng)畫開始前X,Y的縮放,0.0為不顯示, 1.0為正常大小android:fromYScale="0.0"android:interpolator="@android:anim/decelerate_interpolator" //動(dòng)畫插入器android:pivotX="50%" //屬性為動(dòng)畫相對(duì)于物件的X,Y坐標(biāo)的開始位置android:pivotY="50%" //兩個(gè)都為50%表示動(dòng)畫從自身中間開始android:repeatCount="1" //動(dòng)畫重復(fù)的計(jì)數(shù),動(dòng)畫將會(huì)執(zhí)行該值+1次android:repeatMode="reverse" //動(dòng)畫重復(fù)的模式,reverse為反向 android:startOffset="0" //動(dòng)畫多次執(zhí)行的間隔時(shí)間,若執(zhí)行一次,執(zhí)行前會(huì)暫停這段時(shí)間,單位毫秒android:toXScale="1.5" //動(dòng)畫最終縮放的倍數(shù), 1.0為正常大小,大于1.0放大android:toYScale="1.5" />3.rotate畫面旋轉(zhuǎn)動(dòng)畫效果
<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android"android:duration="500"android:fromDegrees="0" //動(dòng)畫開始時(shí)的角度 android:toDegrees="-360" //動(dòng)畫結(jié)束時(shí)物件的旋轉(zhuǎn)角度,正代表順時(shí)針android:interpolator="@android:anim/accelerate_decelerate_interpolator"android:pivotX="50%" //屬性為動(dòng)畫相對(duì)于物件的X,Y坐標(biāo)的開始位置android:pivotY="50%"/>4.translate畫面位置移動(dòng)動(dòng)畫效果
<?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android"android:duration="500"android:fromXDelta="100" //起始時(shí)X,Y座標(biāo),屏幕右下角的座標(biāo)是X:320,Y:480android:fromYDelta="0" android:interpolator="@android:anim/cycle_interpolator"android:toXDelta="0" //動(dòng)畫結(jié)束時(shí)X,Y的座標(biāo)android:toYDelta="0" />5.set組合動(dòng)畫效果
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"><alphaandroid:duration="500"android:fromAlpha="1.0"android:toAlpha="0.0" /><scaleandroid:fromXScale="0.0"android:toXScale="1.5"/> </set>動(dòng)畫監(jiān)聽器Animation.AnimationListener:
?有時(shí)可能我們要在動(dòng)畫的每個(gè)周期里面做不同的操作,這時(shí)候就要借助動(dòng)畫監(jiān)聽器了
alphaAnimation.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {//動(dòng)畫開始時(shí)調(diào)用}@Overridepublic void onAnimationEnd(Animation animation) {//動(dòng)畫結(jié)束時(shí)調(diào)用}@Overridepublic void onAnimationRepeat(Animation animation) {//動(dòng)畫重復(fù)時(shí)調(diào)用}});幾種自帶的動(dòng)畫插入器
AccelerateInterpolator 加速,開始時(shí)慢中間加速
DecelerateInterpolator 減速,開始時(shí)快然后減速
AccelerateDecelerateInterolator 先加速后減速,開始結(jié)束時(shí)慢,中間加速
AnticipateInterpolator 反向,先向相反方向改變一段再加速播放
AnticipateOvershootInterpolator 反向加超越,先向相反方向改變,再加速播放,會(huì)超出目的值然后緩慢移動(dòng)至目的值
BounceInterpolator 跳躍,快到目的值時(shí)值會(huì)跳躍,如目的值100,后面的值可能依次為85,77,70,80,90,100
CycleIinterpolator 循環(huán),動(dòng)畫循環(huán)一定次數(shù),值的改變?yōu)橐徽液瘮?shù):Math.sin(2* mCycles* Math.PI* input)
LinearInterpolator 線性,線性均勻改變
OvershootInterpolator超越,最后超出目的值然后緩慢改變到目的值
2、Frame Animation(Drawable Animation)逐幀動(dòng)畫
??如果要做很炫酷的下拉刷新或者loading動(dòng)畫,可以考慮使用Airbnb開源的動(dòng)畫框架Lottie
??簡單講就是把幾個(gè)靜態(tài)的圖片快速播放形成動(dòng)畫,可以使用AnimationDrawable,官方推薦使用XML文件,放在res/drawable/路徑下。
具體實(shí)現(xiàn)過程:
1.在res/drawable目錄下一個(gè)xml文件:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android"android:oneshot="false"><itemandroid:drawable="@mipmap/lottery_1"android:duration="200" /><itemandroid:drawable="@mipmap/lottery_2"android:duration="200" /><itemandroid:drawable="@mipmap/lottery_3"android:duration="200" /> </animation-list>根節(jié)點(diǎn)是animation-list(動(dòng)畫列表),里面有一個(gè)或者多個(gè)item節(jié)點(diǎn)組成,oneshot屬性表示是否只播放一次,true表示只會(huì)播放一次,false表示一直循環(huán)播放,內(nèi)部用item節(jié)點(diǎn)聲明一個(gè)動(dòng)畫幀,android:drawable指定此幀動(dòng)畫所對(duì)應(yīng)的圖片資源,android:druation代表此幀持續(xù)的時(shí)間,整數(shù),單位為毫秒。
2.用ImageView控件作為動(dòng)畫載體來顯示動(dòng)畫:
imageView.setImageResource(R.drawable.lottery_animlist); AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable(); animationDrawable.start();animationDrawable.stop();onCreate方法中我們運(yùn)行一下,發(fā)現(xiàn)動(dòng)畫沒有運(yùn)行而是停留在第一幀,那是因?yàn)锳nimationDrawable播放動(dòng)畫是依附在window上面的,而在Activity onCreate方法中調(diào)用時(shí)Window還未初始化完畢,所有才會(huì)停留在第一幀,要想實(shí)現(xiàn)播放必須在onStart或者onWindowFocusChanged中調(diào)用start方法。
總結(jié):
? ?Frame Animation(逐幀動(dòng)畫)相對(duì)來說比較簡單,但是在實(shí)際開發(fā)中使用的頻率還是比較高的。希望以這個(gè)小例子能夠掌握逐幀動(dòng)畫,但是逐幀動(dòng)畫只能實(shí)現(xiàn)比較小的動(dòng)畫效果,如果復(fù)雜而且?guī)瑪?shù)比較多的動(dòng)畫不太建議使用逐幀動(dòng)畫,一方面是因?yàn)闀?huì)造成OOM,另一方面會(huì)顯得很卡,如果真是超級(jí)復(fù)雜的動(dòng)畫的話建議選擇雙緩沖繪制View來實(shí)現(xiàn)。
3.Property Animation? 屬性動(dòng)畫
Property Animation產(chǎn)生的背景:
補(bǔ)間動(dòng)畫只是改變了View對(duì)象繪制的位置,而沒有改變View對(duì)象本身,?如果要實(shí)現(xiàn)既要有動(dòng)畫效果又要使得View本身得到真正改變,那就要借助屬性動(dòng)畫了,這也是屬性動(dòng)畫引入的原因。它能夠更加靈活的實(shí)現(xiàn)各種效果,不僅限于類似補(bǔ)間動(dòng)畫實(shí)現(xiàn)的哪幾種效果。
Property Animation相關(guān)類
? ?屬性動(dòng)畫,根據(jù)字面理解可以通過修改物件的屬性值以達(dá)到動(dòng)畫效果。
| 類名 | 用途 |
| ValueAnimator | 屬性動(dòng)畫主要的計(jì)時(shí)器,也計(jì)算動(dòng)畫后的屬性的值,動(dòng)畫的執(zhí)行類 |
| ObjectAnimator ? | ValueAnimator的一個(gè)子類,允許你設(shè)置一個(gè)目標(biāo)對(duì)象和對(duì)象的屬性進(jìn)行動(dòng)畫,動(dòng)畫的執(zhí)行類 |
| AnimatorSet | 提供組織動(dòng)畫的結(jié)構(gòu),使它們能相關(guān)聯(lián)得運(yùn)行,用于控制一組動(dòng)畫的執(zhí)行 |
| AnimatorInflater? | 用戶加載屬性動(dòng)畫的xml文件 |
| Evaluators? | 屬性動(dòng)畫計(jì)算器,告訴了屬性動(dòng)畫系統(tǒng)如何計(jì)算給出屬性的值 |
| Interpolators | 動(dòng)畫插入器,定義動(dòng)畫的變化率 |
?
ObjectAnimator:
? ?ValueAnimator的一個(gè)子類,允許你設(shè)置一個(gè)目標(biāo)對(duì)象和對(duì)象的屬性進(jìn)行動(dòng)畫。當(dāng)這個(gè)類計(jì)算好一個(gè)動(dòng)畫的新值后,相應(yīng)的會(huì)更新其屬性。大多數(shù)時(shí)候你都會(huì)想用ObjectAnimator,因?yàn)樗沟脛?dòng)畫值到目標(biāo)對(duì)象的處理更簡單了。
1.以實(shí)現(xiàn)一個(gè)View透明漸變效果為例進(jìn)行說明
這里需要注意是的屬性動(dòng)畫文件存放目錄為res/animator
<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="500"android:propertyName="alpha" //表示修改的物件的哪個(gè)屬性值,這里是透明度android:repeatCount="1" android:repeatMode="reverse" android:startOffset="200" //動(dòng)畫多次執(zhí)行的間隔時(shí)間,如果只執(zhí)行一次,執(zhí)行前會(huì)暫停這段時(shí)間,單位毫秒 android:valueFrom="0.0" //表示從哪個(gè)狀態(tài)值開始動(dòng)畫android:valueTo="1.0" //表示到哪個(gè)狀態(tài)值結(jié)束動(dòng)畫android:valueType="floatType" /> //類型估值,主要用于設(shè)置動(dòng)畫操作屬性的值通過上面的xml屬性可以看出和補(bǔ)間動(dòng)畫基本上一致,然后通過AnimatorInflater 來加載xml中的動(dòng)畫
也可以用java實(shí)現(xiàn)
ObjectAnimator alphaAnimation = ObjectAnimator.ofFloat(imageView, "alpha", 0f, 1f);alphaAnimation.setDuration(500);alphaAnimation.setRepeatCount(0);alphaAnimation.setRepeatMode(ValueAnimator.REVERSE);alphaAnimation.setStartDelay(200);alphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());alphaAnimation.start();ObjectAnimator 提供了以下幾個(gè)方法:ofFloat(),ofInt(),ofObject(),ofArgb(),ofPropertyValuesHolder()這幾個(gè)方法都是設(shè)置動(dòng)畫作用的元素、作用的屬性、動(dòng)畫開始、結(jié)束、以及中間的任意個(gè)屬性值。?
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.animator_alpha); anim.setTarget(imageView); anim.start();2.如何實(shí)現(xiàn)一個(gè)組合動(dòng)畫
? ? 舉例我們同時(shí)對(duì)一個(gè)控件進(jìn)行寬高兩個(gè)維度的縮放
? 方式一:使用AnimatorSet
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"android:ordering="together"><objectAnimatorandroid:duration="500"android:propertyName="scaleX"android:repeatCount="1"android:repeatMode="reverse"android:valueFrom="1.0"android:valueTo="1.5"android:valueType="floatType" /><objectAnimatorandroid:duration="500"android:propertyName="scaleY"android:repeatCount="1"android:repeatMode="reverse"android:valueFrom="1.0"android:valueTo="1.5"android:valueType="floatType" /></set>方式二:使用PropertyValuesHolder
PropertyValuesHolder scaleXValuesHolder = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 1.5f); PropertyValuesHolder scaleYValuesHolder = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 1.5f); ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(imageView, scaleXValuesHolder, scaleYValuesHolder);objectAnimator.setDuration(500);objectAnimator.setRepeatCount(1);objectAnimator.setRepeatMode(ValueAnimator.REVERSE);objectAnimator.start();通過這種方式只能實(shí)現(xiàn)同時(shí)執(zhí)行的動(dòng)畫組合相比AnimatorSet就沒那么豐富了,PropertyValuesHolder 提供的函數(shù)方法有如下幾種:ofInt()、ofFloat()、ofObject()、ofKeyframe()。
方式三:使用ViewPropertyAnimator
ViewPropertyAnimator viewPropertyAnimator=imageView.animate();viewPropertyAnimator.scaleXBy(1.0f).scaleX(1.5f).scaleYBy(1.0f).scaleY(1.5f).setDuration(500).start();多屬性動(dòng)畫,作用于View,能夠?qū)崿F(xiàn)的動(dòng)畫相對(duì)單一,只能實(shí)現(xiàn)比如縮放,透明度改變,平移、旋轉(zhuǎn)等,具體函數(shù)名字:平移 translationX,translationY, X,Y,縮放 scaleX,scaleY, 旋轉(zhuǎn) rotationX, rotationY,透明度 alpha
objectAnimator.addListener同樣可以設(shè)置監(jiān)聽器
總結(jié)
以上是生活随笔為你收集整理的Android—逐帧、补间、属性动画的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谁抢走了中国男人的老婆?
- 下一篇: 在线学习新编程 技巧全攻略