1、Tween Animation 補間動畫
這類動畫比較簡單,一般就是平移、縮放、旋轉、透明度,或者其組合,可以用代碼或者xml文件的形式,推薦使用xml文件形式,因爲可以複用。
四個動畫效果實現類:TranslateAnimation、ScaleAnimation、RotateAnimation、AlphaAnimation、AnimationSet,對應的的XML標籤爲translate、 scale、 rotate、alpha、set,其中set裏還可以放set,然後放在放置在res/anim/目錄下,關於詳細使用這裏不再做介紹。
1.alpha漸變透明度動畫效果
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500" //動畫持續時間
android:fromAlpha="1.0" //透明度變化
android:toAlpha="0.0" />
2.scale漸變尺寸縮放動畫效果
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXScale="0.0" // 動畫開始前X,Y的縮放,0.0爲不顯示, 1.0爲正常大小
android:fromYScale="0.0"
android:interpolator="@android:anim/decelerate_interpolator" //動畫插入器
android:pivotX="50%" //屬性爲動畫相對於物件的X,Y座標的開始位置
android:pivotY="50%" //兩個都爲50%表示動畫從自身中間開始
android:repeatCount="1" //動畫重複的計數,動畫將會執行該值+1次
android:repeatMode="reverse" //動畫重複的模式,reverse爲反向
android:startOffset="0" //動畫多次執行的間隔時間,若執行一次,執行前會暫停這段時間,單位毫秒
android:toXScale="1.5" //動畫最終縮放的倍數, 1.0爲正常大小,大於1.0放大
android:toYScale="1.5" />
3.rotate畫面旋轉動畫效果
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromDegrees="0" //動畫開始時的角度
android:toDegrees="-360" //動畫結束時物件的旋轉角度,正代表順時針
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%" //屬性爲動畫相對於物件的X,Y座標的開始位置
android:pivotY="50%"/>
4.translate畫面位置移動動畫效果
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="100" //起始時X,Y座標,屏幕右下角的座標是X:320,Y:480
android:fromYDelta="0"
android:interpolator="@android:anim/cycle_interpolator"
android:toXDelta="0" //動畫結束時X,Y的座標
android:toYDelta="0" />
5.set組合動畫效果
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
<scale
android:fromXScale="0.0"
android:toXScale="1.5"/>
</set>
動畫監聽器Animation.AnimationListener:
有時可能我們要在動畫的每個週期裏面做不同的操作,這時候就要藉助動畫監聽器了
alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
//動畫開始時調用
}
@Override
public void onAnimationEnd(Animation animation) {
//動畫結束時調用
}
@Override
public void onAnimationRepeat(Animation animation) {
//動畫重複時調用
}
});
幾種自帶的動畫插入器
AccelerateInterpolator 加速,開始時慢中間加速
DecelerateInterpolator 減速,開始時快然後減速
AccelerateDecelerateInterolator 先加速後減速,開始結束時慢,中間加速
AnticipateInterpolator 反向,先向相反方向改變一段再加速播放
AnticipateOvershootInterpolator 反向加超越,先向相反方向改變,再加速播放,會超出目的值然後緩慢移動至目的值
BounceInterpolator 跳躍,快到目的值時值會跳躍,如目的值100,後面的值可能依次爲85,77,70,80,90,100
CycleIinterpolator 循環,動畫循環一定次數,值的改變爲一正弦函數:Math.sin(2* mCycles* Math.PI* input)
LinearInterpolator 線性,線性均勻改變
OvershootInterpolator超越,最後超出目的值然後緩慢改變到目的值
2、Frame Animation(Drawable Animation)逐幀動畫
如果要做很炫酷的下拉刷新或者loading動畫,可以考慮使用Airbnb開源的動畫框架Lottie
簡單講就是把幾個靜態的圖片快速播放形成動畫,可以使用AnimationDrawable,官方推薦使用XML文件,放在res/drawable/路徑下。
具體實現過程:
1.在res/drawable目錄下一個xml文件:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@mipmap/lottery_1"
android:duration="200" />
<item
android:drawable="@mipmap/lottery_2"
android:duration="200" />
<item
android:drawable="@mipmap/lottery_3"
android:duration="200" />
</animation-list>
根節點是animation-list(動畫列表),裏面有一個或者多個item節點組成,oneshot屬性表示是否只播放一次,true表示只會播放一次,false表示一直循環播放,內部用item節點聲明一個動畫幀,android:drawable指定此幀動畫所對應的圖片資源,android:druation代表此幀持續的時間,整數,單位爲毫秒。
2.用ImageView控件作爲動畫載體來顯示動畫:
imageView.setImageResource(R.drawable.lottery_animlist);
AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable();
animationDrawable.start();
animationDrawable.stop();
onCreate方法中我們運行一下,發現動畫沒有運行而是停留在第一幀,那是因爲AnimationDrawable播放動畫是依附在window上面的,而在Activity onCreate方法中調用時Window還未初始化完畢,所有才會停留在第一幀,要想實現播放必須在onStart或者onWindowFocusChanged中調用start方法。
總結:
Frame Animation(逐幀動畫)相對來說比較簡單,但是在實際開發中使用的頻率還是比較高的。希望以這個小例子能夠掌握逐幀動畫,但是逐幀動畫只能實現比較小的動畫效果,如果複雜而且幀數比較多的動畫不太建議使用逐幀動畫,一方面是因爲會造成OOM,另一方面會顯得很卡,如果真是超級複雜的動畫的話建議選擇雙緩衝繪製View來實現。
3.Property Animation 屬性動畫
Property Animation產生的背景:
補間動畫只是改變了View對象繪製的位置,而沒有改變View對象本身, 如果要實現既要有動畫效果又要使得View本身得到真正改變,那就要藉助屬性動畫了,這也是屬性動畫引入的原因。它能夠更加靈活的實現各種效果,不僅限於類似補間動畫實現的哪幾種效果。
Property Animation相關類
屬性動畫,根據字面理解可以通過修改物件的屬性值以達到動畫效果。
類名 | 用途 |
ValueAnimator | 屬性動畫主要的計時器,也計算動畫後的屬性的值,動畫的執行類 |
ObjectAnimator | ValueAnimator的一個子類,允許你設置一個目標對象和對象的屬性進行動畫,動畫的執行類 |
AnimatorSet | 提供組織動畫的結構,使它們能相關聯得運行,用於控制一組動畫的執行 |
AnimatorInflater | 用戶加載屬性動畫的xml文件 |
Evaluators | 屬性動畫計算器,告訴了屬性動畫系統如何計算給出屬性的值 |
Interpolators | 動畫插入器,定義動畫的變化率 |
ObjectAnimator:
ValueAnimator的一個子類,允許你設置一個目標對象和對象的屬性進行動畫。當這個類計算好一個動畫的新值後,相應的會更新其屬性。大多數時候你都會想用ObjectAnimator,因爲它使得動畫值到目標對象的處理更簡單了。
1.以實現一個View透明漸變效果爲例進行說明
這裏需要注意是的屬性動畫文件存放目錄爲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" //表示修改的物件的哪個屬性值,這裏是透明度
android:repeatCount="1"
android:repeatMode="reverse"
android:startOffset="200" //動畫多次執行的間隔時間,如果只執行一次,執行前會暫停這段時間,單位毫秒
android:valueFrom="0.0" //表示從哪個狀態值開始動畫
android:valueTo="1.0" //表示到哪個狀態值結束動畫
android:valueType="floatType" /> //類型估值,主要用於設置動畫操作屬性的值
通過上面的xml屬性可以看出和補間動畫基本上一致,然後通過AnimatorInflater 來加載xml中的動畫
也可以用java實現
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 提供了以下幾個方法:ofFloat(),ofInt(),ofObject(),ofArgb(),ofPropertyValuesHolder()這幾個方法都是設置動畫作用的元素、作用的屬性、動畫開始、結束、以及中間的任意個屬性值。
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.animator_alpha);
anim.setTarget(imageView);
anim.start();
2.如何實現一個組合動畫
舉例我們同時對一個控件進行寬高兩個維度的縮放
方式一:使用AnimatorSet
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:duration="500"
android:propertyName="scaleX"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="1.0"
android:valueTo="1.5"
android:valueType="floatType" />
<objectAnimator
android: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();
通過這種方式只能實現同時執行的動畫組合相比AnimatorSet就沒那麼豐富了,PropertyValuesHolder 提供的函數方法有如下幾種: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();
多屬性動畫,作用於View,能夠實現的動畫相對單一,只能實現比如縮放,透明度改變,平移、旋轉等,具體函數名字:平移 translationX,translationY, X,Y,縮放 scaleX,scaleY, 旋轉 rotationX, rotationY,透明度 alpha
objectAnimator.addListener同樣可以設置監聽器