動畫做爲展示動態效果不可缺乏的一環,仍是異常重要的,其主要運用在View
中。 按照Android
發展史能夠分紅三個大類:逐幀動畫、補間動畫、屬性動畫。 在如今的實際開發裏面,使用不少的仍是屬性動畫相關的東西,前兩種動畫已經不大經常使用,漸漸淡出了人們的視野。在這裏只是簡單介紹。html
這種原理就相似於gif圖,播放全部已有的幀,經過人眼的短暫視覺殘留來完成動畫。 等價於Android
裏面的AnimationDrawable
java
XML
進行定義須要在 <animation-list .../>
標籤下使用 <item .../>
子元素標籤訂義動畫的所有幀(引入每一幀對應的資源文件),並指定各幀的持續時間。以完成目的。android
該文件建立在res/drawable
文件目錄之下設計模式
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true|false">
<item android:drawable="xxx" android:duration="xx"/>
<!-- more... -->
</animation-list>
複製代碼
其中oneshot
表示該動畫是否循環播放,true
表示只播放一次,false
表示無限循環。app
以後在ImageView
裏面設置對應的資源便可。 只須要獲取到對應的AnimationDrawable
對象,便可經過start()
以及stop()
方法來控制動畫的開始與中止。ide
初始化AnimationDrawable
對象後,經過addFrame(Drawable,int)
來進行加入,分別表明對應幀和持續時間。 直接在ImageView
裏面setDrawable()
來進行綁定。 setOneShot(true)
設置動畫是都循環播放。 一樣的,使用start()
以及stop()
方法來控制動畫的開始與中止。post
使用太多較大的圖片容易引發OOM動畫
顧名思義,就是開發者(咱們)只須要給出動畫的第一幀以及最後一幀,經過系統自動實現中間的過渡動做。ui
Android
幫提供瞭如下的幾種屬性的動畫this
Alpha
translate
scale
rotate
能夠經過XML
文件對他們進行設置,在代碼之中分別對應AlphaAnimation
/TranslateAnimation
/ScaleAnimation
/RotateAnimation
這四個類,共同父類爲Animation
具體的不會過多展開講解,可參考該博客
XML
進行定義須要將對應的資源文件放於目錄res/anim
文件下
一些屬性:
duration
持續時間
interpolator
插值器,控制動畫的變化速率。
在Android
裏面自帶如下實現:
AccelerateDecelerateInterpolator
在動畫開始與結束的地方速率改變比較慢,在中間的時候加速
AccelerateInterpolator
在動畫開始的地方速率改變比較慢,而後開始加速
AnticipateInterpolator
開始的時候進行反向效果真後按照預期效果進行
AnticipateOvershootInterpolator
開始的時候進行反向效果真後超出預期值後返回最後需求的狀態
BounceInterpolator
動畫結束的時候會重複最後一小段時間內的動畫效果
CycleInterpolator
動畫循環播放特定的次數,速率的大小改變聽從正弦曲線
DecelerateInterpolator
在動畫開始快而後速率減少
LinearInterpolator
勻速改變
OvershootInterpolator
超出預期值後再回到最後的狀態
這些插值器都可以經過@android.anim/xxx
進行引用。
fillAfter
動畫結束後是否停留在結束位
而在對應的xml
屬性之中,經過設定fromXxx
和toXxx
屬性來設定對應屬性的開始值和終點值。 以移動爲例:
<translate android:fromXDelta="0" android:toXDelta="100" android:fromYDelta="0" android:toYDelta="100" />
複製代碼
X和Y對應的是X方向與Y方向的操做。 其中對於透明度的設置範圍是-1.0-1.0
縮放值跟的是相對應的倍數,例如0.5
是縮小一半,2.0
是放大一倍 而後在rotate
以及scale
範圍裏面還有兩個參數pivotX
/pivotY
來表示操做的中心點(起始點) 對應的有幾種表示方式,以pivotX
爲例子講解
10
:動畫開始X方向的點爲View
左上角的點 在x方向 加上 10像素的位置10%
: 動畫開始X方向的點View
左上角的點 在x方向 加上 自身寬度乘上10%的位置10%p
:動畫開始X方向的點離View
左上角的點 在x方向 加上 父控件寬度乘上10%數值的位置該方法經過實例化對應的動畫對象來進行相對應的設置。 這些動畫的使用都是調用View.startAnimation(anim)
開始動畫 經過能夠經過setDuration(int)
方法設置動畫運行的時間
translate
Animation translateAnimation = new TranslateAnimation(0,500,0,500);
/** * 1. fromXDelta :視圖在水平方向x 移動的起始值 * 2. toXDelta :視圖在水平方向x 移動的結束值 * 3. fromYDelta :視圖在豎直方向y 移動的起始值 * 4. toYDelta:視圖在豎直方向y 移動的結束值 */
複製代碼
scale
Animation scaleAnimation= new ScaleAnimation(0,2,0,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
/** * 1. fromX :動畫在水平方向X的結束縮放倍數 * 2. toX :動畫在水平方向X的結束縮放倍數 * 3. fromY :動畫開始前在豎直方向Y的起始縮放倍數 * 4. toY:動畫在豎直方向Y的結束縮放倍數 * 5. pivotXType:縮放軸點的x座標的模式 * 6. pivotXValue:縮放軸點x座標的相對值 * 7. pivotYType:縮放軸點的y座標的模式 * 8. pivotYValue:縮放軸點y座標的相對值 * pivotXType = Animation.ABSOLUTE:縮放軸點的x座標 = View左上角的原點 在x方向 加上 pivotXValue數值的點(y方向同理) * pivotXType = Animation.RELATIVE_TO_SELF:縮放軸點的x座標 = View左上角的原點 在x方向 加上 自身寬度乘上pivotXValue數值的值(y方向同理) * pivotXType = Animation.RELATIVE_TO_PARENT:縮放軸點的x座標 = View左上角的原點 在x方向 加上 父控件寬度乘上pivotXValue數值的值 (y方向同理) */
複製代碼
Rotate
Animation rotateAnimation = new RotateAnimation(0,270,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
/** * 1. fromDegrees :動畫開始時 視圖的旋轉角度(正數 = 順時針,負數 = 逆時針) * 2. toDegrees :動畫結束時 視圖的旋轉角度(正數 = 順時針,負數 = 逆時針) * 3. pivotXType:旋轉軸點的x座標的模式 * 4. pivotXValue:旋轉軸點x座標的相對值 * 5. pivotYType:旋轉軸點的y座標的模式 * 6. pivotYValue:旋轉軸點y座標的相對值 * pivotXType具體值以及做用同上 */
複製代碼
alpha
Animation alphaAnimation = new AlphaAnimation(1,0);
// 1. fromAlpha:動畫開始時視圖的透明度(取值範圍: -1 ~ 1)
// 2. toAlpha:動畫結束時視圖的透明度(取值範圍: -1 ~ 1)
複製代碼
動畫的設置優先級:子動畫>動畫集。即,子動畫設置了無限循環,動畫集設置了只運行一次,運行的時候仍是無限循環的模式。
固然,也能夠經過本身需求對補間動畫進行定義,繼承Animation
類,並重寫applyTranformation()
方法 具體的就不詳細講述了,由於:
咱們爲何不用屬性動畫呢?
屬性動畫直白來講,是對任意對象的任意屬性進行動畫過渡,是補間動畫的增強版 其優勢:
View
的屬性值,在動畫的時候已經對應改變了view的屬性(響應點擊事件)咱們一般使用如下兩個類
ValueAnimator
在屬性動畫裏面使用到的時間引擎,計算對應的屬性值
ObjectAnimator
是上者的子類,對指定對象的屬性執行動畫
爲了健壯性,通常是在代碼裏面聲明對象,在這裏就不介紹XML
設置的方式
ValueAnimator
經過不斷控制值的變化,在不斷手動賦值給對象的屬性,從而實現動畫效果。
過程:
設置動畫的運行時長,動畫效果以及開始和結束的屬性值
設置估值器
該類描述動畫如何從初始值過渡到結束值的邏輯
添加AnimatorUpdateListener
,該接口會直接回調當前狀態的Animation
,經過animation.getAnimatedValue()
(記得強制轉換,由於該方法返回的是Object)獲取到當前的值
將值設置到給須要進行變換的屬性上面
通知View
進行重繪
postInvalidate()
invalidate()
在這裏面主要是使用ValueAnimator.ofXxx(...values)
靜態方法來獲取相對應的ValueAnimator
含有ofInt()
/ofFloat()
/ofObject()
/ofArgb()
/ofPropertyValuesHolder()
這幾種方法 分別對應其中的過渡值:整形值、浮點值、對象、顏色值、存儲屬性的動畫改變值 實際開發裏面經常使用前面三種,在使用的時候傳入對應屬性的變化值
Animator animator = ValueAnimator.ofFloat(0, 3f);
// 設置運行時間
animator.setDuration((long) (time * 1000));
// 設置重複次數
animator.setRepeatCount(0);
// 設置重複播放動畫模式
// ValueAnimator.RESTART(默認):正序重放
// ValueAnimator.REVERSE:倒序回放
animmator.setRepeatMode(ValueAnimator.RESTART);
// 設置插值器
animator.setInterpolator(new LinearInterpolator());
// 添加監聽
animator.addUpdateListener(animation -> {
float f = (float) animation.getAnimatedValue();
// 對view進行操做
postInvalidate();
});
animator.start();
複製代碼
可是對於對象的過渡,咱們須要自定義估值器(自定義類實現TypeEvaluator
接口) 複寫evaluate(float fraction, Object startValue, Object endValue)
方法 分別對應:
最後須要返回對象通過過渡邏輯計算後的值
本質上仍是在操做值,不過將多個值所有封裝到了一個對象裏面
ObjectAnimator
直接傳入對象以及對象的屬性名以及操做值來實現動畫效果
該類相比於ValueAnimator
來講,只是少了賦值給對應屬性這一步
新建對象與ValueAnimator
類似,也是經過ofXxx
方法,不過傳入的參數有區別,加入了對應的新參數 (Object object, String property, ....values)
使用樣例以下
ObjectAnimator animator = ObjectAnimator.ofFloat(this, "translationX", 0, 200f);
animator.setDuration((long) (actionTime * 1000));
animator.start();
複製代碼
對於ofPropertyValuesHolder()
來講,只須要傳入(Object,PropertyValuesHolder ... values)
便可
PropertyValuesHolder
存放作動畫的對應屬性以及期間的變化值,聲明方式與ValueAnimator
相似,不過在以前須要傳入屬性名
對於該類,在最開始有一個簡單解釋:
此類包含有關屬性的信息以及該屬性在動畫期間應採用的值。 PropertyValuesHolder對象可用於使用ValueAnimator或ObjectAnimator建立動畫,這些動畫可並行操做多個不一樣的屬性。
可等價於動畫集合AnimatorSet
,在ObjectAnimator
和ValueAnimator
之中調用並傳入參數便可。
PropertyValuesHolder upX = PropertyValuesHolder.ofFloat("translationX", 0, -20);
PropertyValuesHolder upY = PropertyValuesHolder.ofFloat("translationY", 0, -20);
ObjectAnimator animatorUp = ObjectAnimator.ofPropertyValuesHolder(this, upX, upY)
.setDuration((long) (actionTime * 1000));
animatorUp.setStartDelay((long) (actionTime * 100));
animatorUp.start();
複製代碼
除了AnimatorUpdateListener
來監聽過程當中的值,也可以經過添加AnimatorListener
來實現動畫過程的監聽以完成交互 實現該接口須要重寫如下方法:
onAnimationStart
動畫開始時
onAnimationRepeat
動畫重複時
onAnimationCancel
動畫取消時
onAnimationEnd
動畫結束時
在Animation
中經過addListener
方法傳入。(動畫對象均可以調用addListener
方法來實現監聽) AnimatorUpdateListener
只可以用於ValueAnimator
之中(只有該類暴露了設置的接口)
倘若重寫四個方法太繁瑣,可使用AnimatorListenerAdapter
來指定複寫某方法
前提:
get
以及set
屬性 如下方法針對沒有直接的get
與set
方法的狀況
get
與set
TypeEvaluator
類實現屬性變化的邏輯ofObjecct()
方法手動設置對應屬性的時候,注意:
set
/get
方法set
方法對該屬性的改變會經過某種方式反映出來 例如view.setWidth()
與view.getWidth()
並不會完成預期效果ViewPropertyAnimator
爲了面向對象而新增的一個類,能夠理解爲是屬性動畫的一種簡寫方式。
經過View.animate().xxx().xxx()
進行鏈式調用。 在animate()
方法後返回了一個ViewPropertyAnimator
對象,以後全部方法都是在這個基礎上進行調用。
一個簡單例子:
view.animate().alpha(0f);
// 單個動畫設置:將按鈕變成透明狀態
view.animate().alpha(0f).setDuration(3 * 1000).setInterpolator(new BounceInterpolator());
// 單個動畫效果設置以及參數設置
view.animate().alpha(0f).x(50).y(50);
/** * 組合動畫:將按鈕變成透明狀態再移動到(50,50)處 * 特別注意: * 動畫會自啓動,無需調用start()方法.由於新的接口中使用了隱式啓動動畫的功能,只要咱們將動畫定義完成後,動畫就會自動啓動 * 該機制對於組合動畫也一樣有效,只要不斷地連綴新的方法,那麼動畫就不會馬上執行,等到全部在ViewPropertyAnimator上設置的方法都執行完畢後,動畫就會自啓動 */
複製代碼
AnimatorSet
承載一個動畫集合,能夠經過相關的方法調整展現的順序。play()
內部調用Builder()
方法建立對應的對象。 例如:
AnimatorSet s = new AnimatorSet();
s.play(anim1).with(anim2);
s.play(anim2).before(anim3);
s.play(anim4).after(anim3);
複製代碼
在xml
中使用<set ... />
標籤來結合多個Animation
後在代碼裏面經過如下方式加載動畫
// 加載動畫資源
Animation anim = AnimationUtils.loadAnimation(this,R.anim.xxx);
//設置動畫結束後保留結束狀態
anim.setFillAfter(true);
// 以後經過ImageView裏面的startAnimation進行動畫的開始
ImageView im = findViewById(xxx);
im.startAnimation(anim);
複製代碼
layoutAnimation
針對於ViewGroup
裏面的子元素,譬如說ListView
XML
:<layoutanimation .../>
LayoutAnimationController
在XML
之中指定ViewGroup
的layoutAnimation
屬性便可生效
Activity
切換效果使用overridePendingTransiton(int start,int exit)
,分別傳入動畫的id,在startActivity(intent)
與finish()
方法後生效
避免使用幀動畫(AnimationDrawable
)
防止圖片過大、過多出現OOM的狀況
防止內存泄漏:Activity
退出關閉時關閉無限循環的動畫
使用view
動畫後若要作可見性操做請先clearAAnimation()
清除
儘可能使用dp而不是px
元素交互:
在3.0後,屬性動畫的單擊事件觸發位置爲移動後的位置,可是view動畫仍是在原來的位置
建議開啓硬件加速
提升動畫流暢性
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |