天天看點

屬性動畫進階(二)

ViewPropertyAnimator:
  • 這個機制提供了一個新函數:animate(),我們通過這個新函數來對控件進行操作。
animate()
  • animate()整個系統從調用View的animate()這個新函數開始,這個函數會傳回一個ViewPropertyAnimator對象,可以通過調用這個而對象的函數來設定需要實作動畫的屬性
  • 自動開始動畫,不需要顯示的調用start()函數,這些動畫會再下一次頁面重新整理的時候啟動,如果就繼續添加動畫,他就會繼續講這些動畫添加到下一幀開始的動畫清單中,而當你聲明完畢并結束對UI線程控制的時候,時間隊列機制就可使啟動,動畫開始
  • 流暢:ViewPropertyAnimator擁有一個很流暢的接口(Fluent Interace)它允許将多個函數調用很自然的串在一起,并把一個多屬性的動畫寫成一行代碼,所有的調用都會發那會一個ViewPropertyAnimator執行個體,即生成器模式
使用ViewPropertyAnimator的原因:
  • ViewPRopertyAnimator并沒有像ObjectAnimator一樣使用反射或者JNI技術,它是根據每一額動畫幀計算出對應的所有屬性值,并設定給控件,然後調用一次invalidate()函數進行重繪,進而解決了在使用ObjectAnimator時每個屬性單獨計算,單獨重繪的問題,是以ViewPropertyAnimator相對于ObjectAnimaator群組合動畫,性能有所提升,但是總的來說還是展現在代碼的簡潔上面,因為ObjectAnimator的性能開銷微不足道
為ViewGroup内的元件添加動畫:
  • 如果為listView中的每個Item, 資料變更時添加動畫,那麼使用ViewAnimtor ObjectAnimator, AnimatorSet都是無法做到的
  • 其中為了實作給ViewGroup提供相應的動畫,Android提供了四種方法:
    • layoutAnimator标簽與LayoutAnimationController
      • layoutAnimator标簽在API 11中引入,它是專門針對listview添加入場動畫所使用的,LayoutAnimatorController是他的代碼實作,它可以實作在list view建立時對其中的每個item添加入場動畫,而且動畫可以自定義,然而,在listview建立完成後,如果再添加資料,則新添加的資料是不會有入場動畫的
    • gridLayoutAnimation标簽與GridLayoutAnimationController
      • gridLayoutAnimation标簽也是在API 11時引入的,它是專門針對gridview添加入場動畫所使用的, 同樣GridLayoutAnimationController是他的代碼實作,它可以實作在gridview建立時對其中的每個item添加入場動畫,而且動畫可以自定義,與layoutAnimation标簽相同的是,動畫隻會在初次建立時出現,在gridview建立完成之後是不會存在動畫的
    • android:animateLayoutChanges屬性:
      • 在API 11之後Android為了支援ViewGroup類型,在添加和移除其中的控件時自動添加動畫,提供了這個非常簡單的屬性,所有派生自ViewGroup類的控件都具有此屬性。而且隻要在XML中添加這個屬性,就能實作在添加/删除其中控件時帶有預設動畫,但是動畫不可自定義
    • LayoutTransition
      • 實作在ViewGroup動态添加或者删除其中的控件時指定動畫,動畫可自定義
  • LayoutTransition:
    • 對比animateLayoutChanges="true"來說,LayoutTransition可以自定義标簽
//第一步建立執行個體
LayoutTransition transitioner = new LayoutTransition();
//第二步建立動畫并進行設定
ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f);
transitioner.setAniator(LayoutTransition.DISAPPEARING, animOut);
//将LayoutTransition設定到ViewGroup中,其中LinearLayout等布局都擁有一個專門用來設定LayoutTransition的函數
linearLayout.setLayoutTransition(transitioner);
           
  • int transitionType表示:目前應用動畫的對象範圍,取值如下:
    • APPEARING: 元素在容器中出現時所定義的動畫
    • DISAPPEARING:元素在容器中消失時所定義的動畫
    • CHANGE_APPEARING:由于容器中要顯示一個新的元素,其他需要變化的元素所應用的動畫
    • CHANGE_DISAPPEARING:當容器中某個元素消失時其他元素所應用的動畫

eg:

//建立layoutTransition對象
LayoutTransition layoutTransition = new LayoutTransition();
//建立動畫
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(null,"rotationY", 0f, 360f, 0f);
//設定動畫
layoutTransition.setAnimator(LayoutTransition.APPEARING, objectAnimator);


ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f);
layoutTransition.setAnimator(LayoutTransition.DISAPPEARING, objectAnimator1);
//将動畫加到ViewGroup中
linearLayout.setLayoutTransition(layoutTransition);
           
  • 一般情況下不适用LayoutTransition.CHANGE_APPEARING與LayoutTransition.CHANGE_DISAPPEARING屬性,存在一些問題,這兩個屬性必須在PropertyValueHolder構造動畫中才會有效果,使用ObjectAnimator是不會存在效果的。
LayoutTransition函數 說明
setDuration(long duration) 設定動畫完成所需要的時間
setDuration(int transitionType, long duration) 針對單個Type設定動畫時長
setInterpolator(int transitionType, TimeInterpolator interpolator) 針對單個Type設定插值器
setStartDelay(int transitionType, long delay) 針對單個Type設定動畫延時
setStagger(int transitionType, long duration) 針對單個Type設定每個子item動畫的時間間隔(transitionType是指定type的動畫類型,duration指定各個item的動畫間隔
  • 設定監聽:
public void addTransitionListener(TransitionListener listener)
//任何類型的LayoutTransition開始和結束時都會調用startTransition和endTransition
//LayoutTransition :目前的LayoutTransition執行個體
//ViewGroup  container: 目前應用的LayoutTransition的容器
//View view: 目前在做動畫的View對象
//int transitionType:目前的LayoutTransition類型,取值有APPEARING = 0,、DISAPPEARING = 3、CHANGE_APPEARING = 0和CHANGE_DISAPPEARING = 1

public interfacce TransitionListener{
    public void startTransition(LayoutTransition transition, ViewGroup  container, View view, int transitionType);
    public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType);
 }
           
  • 使用監聽器:添加按鈕和删除按鈕
06-09 12:40:32.301 13183-13183/com.example.adminstator.myviewdesign I/System.out: startandroid.widget.Button
06-09 12:40:32.301 13183-13183/com.example.adminstator.myviewdesign I/System.out: startandroid.widget.LinearLayout
06-09 12:40:32.621 13183-13183/com.example.adminstator.myviewdesign I/System.out: endandroid.widget.LinearLayout
06-09 12:40:32.901 13183-13183/com.example.adminstator.myviewdesign I/System.out: endandroid.widget.Button
06-09 12:40:36.141 13183-13183/com.example.adminstator.myviewdesign I/System.out: startandroid.widget.Button
06-09 12:40:36.461 13183-13183/com.example.adminstator.myviewdesign I/System.out: endandroid.widget.Button
06-09 12:40:36.481 13183-13183/com.example.adminstator.myviewdesign I/System.out: startandroid.widget.LinearLayout
06-09 12:40:36.781 13183-13183/com.example.adminstator.myviewdesign I/System.out: endandroid.widget.LinearLayout
           

繼續閱讀