Android動畫知識彙總


   本文是對Android動畫的彙總關於Android的動畫包括 3.0之前的View Animation,3.0之後的 Property Animator 以及5.0新增的(Touch feedback(觸摸反饋)Reveal effect(揭露效果)Activity transitions(Activity轉換效果)Curved motion(曲線運動)View state changes (視圖狀態改變)Animate Vector Drawables(可繪矢量動畫))6種動畫。


幾種動畫的詳細內容如下:

  1. View Animation :

     第一類是Tween動畫,就是對場景裏的對象不斷的進行圖像變化來產生動畫效果。 

       第二類就是 Frame動畫,即順序的播放事先做好的圖像,與gif圖片原理類似。


       下面就講一下Tweene Animations。

        主要類:

          Animation   動畫

          AlphaAnimation 漸變透明度

          otateAnimation 畫面旋轉

          ScaleAnimation 漸變尺寸縮放

          ranslateAnimation 位置移動

          AnimationSet  動畫集


      以自定義View爲例,該View很簡單,畫面上只有一個圖片。 現在我們要對整個View分別實現各種Tween動畫效果。 

      1) AlphaAnimation實現代碼:  

      //初始化  
      Animation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);  
      //設置動畫時間           
      alphaAnimation.setDuration(3000);  
      this.startAnimation(alphaAnimation);


        其中AlphaAnimation類第一個參數fromAlpha表示動畫起始時的透明度, 第二個參數toAlpha表示動畫結束時的透明度。setDuration用來設置動畫持續時間。

       fromAlpha、toAlpha屬性說明:0.0表示完全透明 1.0表示完全不透明 以上值取0.0-1.0之間的float數據類型的數字

    

      2) RotateAnimation實現代碼:

      Animation rotateAnimation = new RotateAnimation(0f, 360f);  
      rotateAnimation.setDuration(1000);  
      this.startAnimation(rotateAnimation);


      其中RotateAnimation類第一個參數fromDegrees表示動畫起始時的角度, 第二個參數toDegrees表示動畫結束時的角度。另外還可以設置伸縮模式pivotXType、pivotYType, 伸縮動畫相對於x,y 座標的開始位置pivotXValue、pivotYValue等        fromDegrees、toDegrees屬性值說明0.0表示收縮到沒有 1.0表示正常無伸縮 值小於1.0表示收縮 值大於1.0表示放大。 

                              當角度爲負數——表示逆時針旋轉
                              當角度爲正數——表示順時針旋轉
                              (負數from——to正數:順時針旋轉)
                              (負數from——to負數:逆時針旋轉)
                              (正數from——to正數:順時針旋轉)
                              (正數from——to負數:逆時針旋轉)

        pivotX、pivotY屬性值說明:從0%-100%中取值,50%爲物件的X或Y方向座標上的中點位置


      3) ScaleAnimation實現代碼:

       //初始化  
        Animation scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f);  
       //設置動畫時間  
       scaleAnimation.setDuration(500);  
       this.startAnimation(scaleAnimation);

 

      ScaleAnimation類中

      第一個參數fromX ,第二個參數toX:分別是動畫起始、結束時X座標上的伸縮尺寸。

      第三個參數fromY ,第四個參數toY:分別是動畫起始、結束時Y座標上的伸縮尺寸。

      另外還可以設置伸縮模式pivotXType、pivotYType, 伸縮動畫相對於x,y 座標的開始位置pivotXValue、pivotYValue等。

     

     4)TranslateAnimation實現代碼:

       //初始化  
       nimation translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f);  
       //設置動畫時間                
       translateAnimation.setDuration(1000);  
       this.startAnimation(translateAnimation);

   

     TranslateAnimation類 

     第一個參數fromXDelta ,第二個參數toXDelta:分別是動畫起始、結束時X座標。

    第三個參數fromYDelta ,第四個參數toYDelta:分別是動畫起始、結束時Y座標。


      5)AnimationSet實現代碼:


            //初始化 Translate動畫  
        translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f);  
        //初始化 Alpha動畫  
        alphaAnimation = new AlphaAnimation(0.1f, 1.0f);  
      
        //動畫集  
        AnimationSet set = new AnimationSet(true);  
         set.addAnimation(translateAnimation);  
        set.addAnimation(alphaAnimation);  
      
        //設置動畫時間 (作用到每個動畫)  
        set.setDuration(1000);  
        this.startAnimation(set);

   

      6)Interpolator

       用於修改一個動畫過程中的速率,可以定義各種各樣的非線性變化函數,比如加速、減速等。

       在Android中所有的插值器都是Interpolator 的子類,通過 android:interpolator 屬性你可以引用不同的插值器。下面是幾種插值

       你可以通過下面的方式使用它們:

         <set android:interpolator="@android:anim/accelerate_interpolator">
            </set>


       自定義插值器

       如果你對系統提供的插值器不滿意,我們可以創建一個插值器資源修改插值器的屬性,比如修改AnticipateInterpolator的加速速率,調整CycleInterpolator的循環次數等。爲了完成這種需求,我們需要創建XML資源文件,然後將其放於/res/anim下,然後再動畫元素中引用即可。我們先來看一下幾種常見的插值器可調整的屬性:

       <?xml version="1.0" encoding="utf-8"?>
           <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android"
        android:attribute_name="value"
         />

    

       android:factor 浮點值,加速速率,默認爲1

       android:tension 浮點值,起始點後退的張力、拉力數,默認爲2

       android:tension 同上 android:extraTension 浮點值,拉力的倍數,默認爲1.5(2 * 1.5)

       android:cycles int,循環的個數,默認爲1

       android:factor 浮點值,減速的速率,默認爲1

       浮點值,超出終點後的張力、拉力,默認爲2


       比如:res/anim/my_overshoot_interpolator.xml:

      <?xml version="1.0" encoding="utf-8"?>
    <overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:tension="7.0"/>

    This animation XML will apply the interpolator:


          <scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@anim/my_overshoot_interpolator"
        android:fromXScale="1.0"
        android:toXScale="3.0"
        android:fromYScale="1.0"
        android:toYScale="3.0
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="700" />

    如果簡單的修改插值器的屬性值還不能夠滿足我們的需求,那麼就自己來通過實現Interpolator接口來定義自己的插值器了因爲上面所有的Interpolator都實現了Interpolator接口,這個接口定義了一個方法:float getInterpolation(float input);此方法由系統調用,input代表動畫的時間,在0和1之間,也就是開始和結束之間。


    線性(勻速)插值器定義如下:

       

             public float getInterpolation(float input) {  
            return input;  
        }

    加速減速插值器定義如下:

            public float getInterpolation(float input) {  
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;  
        }



   2.PropertyAnimator動畫

  Property Animation動畫有兩個步聚:
    a.計算屬性值
    b.爲目標對象的屬性設置屬性值,即應用和刷新動畫

    1) 計算屬性值

wKioL1f6bGTjC-pjAAGsVzG8ArY297.png-wh_50

     過程一:計算已完成動畫分數 elapsed fraction
   爲了執行一個動畫,你需要創建一個ValueAnimator,並且指定目標對象屬性的開始、結束值和持續時間。在調用start後的整個動畫過程中, ValueAnimator會根據已經完成的動畫時間計算得到一個0到1之間的分數,代表該動畫的已完成動畫百分比。0表示0%,1表示100%。

       過程二:計算插值(動畫變化率)interpolated fraction
當ValueAnimator計算完已完成動畫分數後,它會調用當前設置的TimeInterpolator,去計算得到一個interpolated(插值)分數,在計算過程中,已完成動畫百分比會被加入到新的插值計算中。

       過程三:計算屬性值
當插值分數計算完成後,ValueAnimator 會根據插值分數調用合適的 TypeEvaluator去計算運動中的屬性值。
以上分析引入了兩個概念:已完成動畫分數(elapsed fraction)、插值分數( interpolated fraction
)。

    核心類:

     wKiom1f6bVaAg82VAAAzkTjkLhc773.png-wh_50


    a. Evaluators

    Evaluators 告訴屬性動畫系統如何去計算一個屬性值。它們通過Animator提供的動畫的起始和結束值去計算一個動畫的屬性值。

    屬性系統提供了以下幾種Evaluators:

     1.IntEvaluator

     2.FloatEvaluator

     3.ArgbEvaluator

     這三個由系統提供,分別用於計算int,float,color型(十六進制)屬性的計算器


    b.TypeEvaluator

    一個用於用戶自定義計算器的接口,如果你的對象屬性值類型,不是int,float,或者color類型,你必須實現這個接口,去定義自己的數據類型。TypeEvaluator接口只有一個方法,就是evaluate()方法,它允許你使用的animator返回一個當前動畫點的屬性值。

   c.ValueAnimator

   屬性動畫中的主要的時序引擎,如動畫時間,開始、結束屬性值,相應時間屬性值計算方法等。包含了所有計算動畫值的核心函數。也包含了每一個動畫時間上的細節,信息,一個動畫是否重複,是否監聽更新事件等,並且還可以設置自定義的計算類型。

   使用ValueAnimator實現動畫需要手動更新:


ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i("update", ((Float) animation.getAnimatedValue()).toString());
}
});
animation.setInterpolator(new CycleInterpolator(3));
animation.start();


   d.ObjectAnimator

   繼承自ValueAnimator,允許你指定要進行動畫的對象以及該對象的一個屬性。該類會根據計算得到的新值自動更新屬性。ObjectAnimator的自動更新功能,依賴於屬性身上的setter和getter方法,所以爲了讓ObjectAnimator能夠正確的更新屬性值,你必須遵從以下規範:

1. 該對象的屬性必須有get和set方法(方法的格式必須是駝峯式),方法格式爲set(),因爲ObjectAnimator會自動更新屬性,它必須能夠訪問到屬性的setter方法,比如屬性名爲foo,你就需要一個setFoo()方法,如果setter方法不存在,你有三種選擇:

a.添加setter方法

b.使用包裝類。通過該包裝類通過一個有效的setter方法獲取或者改變屬性值的方法,然後應用於原始對象,比如NOA的AnimatorProxy。

c.使用ValueAnimator代替

(這3點的意思總結起來就是一定要有一個setter方法,讓ObjectAnimator能夠訪問到)

 

如果你爲ObjectAnimator的工廠方法的可變參數只傳遞了一個值,那麼會被作爲動畫的結束值。


   e. AnimatorSet

   提供組合動畫能力的類。並可設置組中動畫的時序關係,如同時播放、有序播放或延遲播放。Elevator會告訴屬性動畫系統如何計算一個屬性的值,它們會從Animator類中獲取時序數據,比如開始和結束值,並依據這些數據計算動畫的屬性值。


   f.ViewPropertyAnimator

   可以方便的爲某個View的多個屬性添加並行的動畫,只使用一個ViewPropertyAnimator對象就可以完成。它的行爲更像一個ObjectAnimator,因爲它修改的是對象的實際屬性值。但它爲一次性給多個屬性添加動畫提供了方便,而且使用ViewPropertyAnimator的代碼更連貫更易讀。

下面的代碼段分別展示了使用多個ObjectAnimator對象、一個ObjectAnimator對象、 ViewPropertyAnimator同時爲一個View的X和Y屬性添加動畫的示例:

多個ObjectAnimator結合AnimatorSet實現


ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();


一個ObjectAnimator結合多個PropertyValuesHolder實現

ropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();

ViewPropertyAnimator: 只需一行代碼

myView.animate().x(50f).y(100f);//myView.animate()直接返回一個ViewPropertyAnimator對象

   g.PropertyValuesHolder

   顧名思義,該類持有屬性,相關屬性值的操作以及屬性的setter,getter方法的創建,屬性值以Keyframe來承載,最終由KeyframeSet統一處理。


   h.KeyFrame

   一個keyframe對象由一對 time / value的鍵值對組成,可以爲動畫定義某一特定時間的特定狀態。每個keyframe可以擁有自己的插值器,用於控制前一幀和當前幀的時間間隔間內的動畫。

Keyframe.ofFloat(0f,0f);

第一個參數爲:要執行該幀動畫的時間節點(elapsed time / duration)

第二個參數爲屬性值。

    因此如果你想指定某一特定時間的特定狀態,那麼簡單的使用ObjectAnimator就滿足不了你了,因爲ObjectAnimator.ofInt(....)類似的工廠方法,無法指定特定的時間點的狀態。

    每個KeyFrame其實也有個Interpolator。如果沒有設置,默認是線性的。之前爲Animator設置的Interpolator是整個動畫的,而系統允許你爲每一KeyFrame的單獨定義Interpolator,系統這樣做的目的是允許你在某一個keyFrame做特殊的處理,也就是整體上是按照你的插值函數來計算,但是,如果你希望某個或某些KeyFrame會有不同的動畫表現,那麼你可以爲這個keyFrame設置Interpolator。因此,Keyframe的定製性更高,你如果想精確控制某一個時間點的動畫值及其運動規律,你可以自己創建特定的Keyframe 。


Keyframe使用

爲了實例化一個keyframe對象,你必須使用某一個工廠方法:ofInt(), ofFloat(), or ofObject() 去獲取合適的keyframe類型,然後你調用ofKeyframe工廠方法去獲取一個PropertyValuesHolder對象,一旦你擁有了該對象,你可以將PropertyValuesHolder作爲參數獲取一個Animator,如下:


Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);//動畫屬性名,可變參數
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)
rotationAnim.setDuration(5000);

   i. KeyFrameSet


   根據Animator傳入的值,爲當前動畫創建一個特定類型的KeyFrame集合。

通常通過ObjectAnimator.ofFloat(…)進行賦值時,這些值其實是通過一個KeyFrameSet來維護的

比如:

ObjectAnimator.ofFloat(target, "translateX", 50, 100, 200);

調用者傳入的values 爲 50,100,200,則numKeyframs = 3,那麼創建出相應的Keyframe爲:

Keyframe(0,50),Keyframe(1/2,100),Keyframe(1,200), 時間點 0,1/2,1 都是按比例劃分的


public static KeyframeSet ofFloat(float... values) {
int numKeyframes = values.length;
FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)];
if (numKeyframes == 1) {
keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f);
keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]);
} else {
keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]);
for (int i = 1; i < numKeyframes; ++i) {
keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);//這裏是關鍵
}
}
return new FloatKeyframeSet(keyframes);


  2) 在XML中聲明屬性動畫

   通過在XML中定義的動畫,可以很方便的在多個Activities中重用而且更容易編輯,複用性強。爲了區分新的屬性動畫,從3.1開始,你應res/animator/下存放屬性動畫的資源文件,使用animator文件夾是可選的,但是如果你想在Eclipse ADT插件中使用佈局編輯工具(ADT 11.0.0+),就必須在res/animator文件夾下存放了,因爲ADT只會查找res/animator文件夾下的屬性動畫資源文件。


屬性動畫支持的Tag有

ValueAnimator - <animator>

ObjectAnimator - <objectAnimator>

AnimatorSet - <set>


<set android:ordering="sequentially">
<set>
<objectAnimator
android:propertyName="x"
android:duration="500"
android:valueTo="400"
android:valueType="intType"/>
<objectAnimator
android:propertyName="y"
android:duration="500"
android:valueTo="300"
android:valueType="intType"/>
</set>
<objectAnimator
android:propertyName="alpha"
android:duration="500"
android:valueTo="1f"/>
</set>


AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
R.anim.property_animator);
set.setTarget(myObject);
set.start();


目錄res/animator/filename.xm


編譯後的資源爲ValueAnimator, ObjectAnimator, or AnimatorSet


XML文件的根元素必須爲<set>,<objectAnimator>, or <valueAnimator>之一。也可以在一個set中組織不同的動畫,包含其它<set>元素,也就是說,可以嵌套。


<set  
android:ordering=["together" | "sequentially"]>  
<objectAnimator  
android:propertyName="string"  
android:duration="int"  
android:valueFrom="float | int | color"  
android:valueTo="float | int | color"  
android:startOffset="int"  
android:repeatCount="int"  
android:repeatMode=["repeat" | "reverse"]  
android:valueType=["intType" | "floatType"]/>  
<animator  
android:duration="int"  
android:valueFrom="float | int | color"  
android:valueTo="float | int | color"  
android:startOffset="int"  
android:repeatCount="int"  
android:repeatMode=["repeat" | "reverse"]  
android:valueType=["intType" | "floatType"]/>  
<set>  
...  
</set>  
</set>


  3.Andriod L的動畫

     Material Design是Google推出的一個全新的設計語言,它的特點就是擬物扁平化。     

     在Android L中新增瞭如下幾種動畫:

      a. Touch feedback(觸摸反饋)

      b. Reveal effect(揭露效果)

      c. Activity transitions(Activity轉換效果)

      d. Curved motion(曲線運動)

      e. View state changes (視圖狀態改變)

      f. Animate Vector Drawables(可繪矢量動畫)


 詳細的內容如下:

    1. 觸摸反饋:

    觸摸反饋最具代表性的就是波紋動畫,比如當點擊按鈕時會從點擊的位置產生類似於波紋的擴散效果。

    1)波紋效果(Ripple):

     可以通過如下代碼設置波紋的背景:android:background="?android:attr/selectableItemBackground"波紋有邊界  android:background="?android:attr/selectableItemBackgroundBorderless"波紋超出邊界


具體代碼如下:

<Button
        android:id="@+id/btn_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn_1"
        android:padding="10px"
        android:layout_below="@id/touch_feedback_ripple_textview"
        />
    <Button
        android:id="@+id/btn_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn_2"
        android:layout_below="@id/btn_1"
        android:padding="10px"
        android:background="?android:attr/selectableItemBackground"/>
    <Button
        android:id="@+id/btn_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn_3"
        android:layout_below="@id/btn_2"
        android:padding="10px"
      android:background="?android:attr/selectableItemBackgroundBorderless"/>

效果如下:

wKioL1f6eEjQ29VnAAFGl6gbEN8743.gif

    2)設置顏色

     我們也可以通過設置xml屬性來調節動畫顏色,從而可以適應不同的主題:

      android:colorControlHighlight:設置波紋顏色 

     android:colorAccent:設置checkbox等控件的選中顏色


   2. Circular Reveal:

   使用方法:

   應用ViewAnimationUtils.createCircularReveal()方法可以去創建一個RevealAnimator動畫 。

   ViewAnimationUtils.createCircularReveal源碼如下:

 public static Animator createCircularReveal(View view,nt centerX,  int centerY, float startRadius, float endRadius) {  
  return new RevealAnimator(view, centerX, centerY, startRadius, endRadius); 
  }

源碼非常簡單,就是通過createCircularReveal方法根據5個參數來創建一個RevealAnimator動畫對象。


這五個參數分別是:

view 操作的視圖

  centerX 動畫開始的中心點X

  centerY 動畫開始的中心點Y

  startRadius 動畫開始半徑

  startRadius 動畫結束半徑


實例代碼:

final View oval = this.findViewById(R.id.oval);  
    oval.setOnClickListener(new View.OnClickListener() {  
        @Override  
        public void onClick(View v) {  
            Animator animator = ViewAnimationUtils.createCircularReveal(  
                    oval,oval.getWidth()/2,oval.getHeight()/2,oval.getWidth(),0);  
            animator.setInterpolator(new AccelerateDecelerateInterpolator());  
            animator.setDuration(2000);  
            animator.start();  
        }  
    });  
      
final View rect = this.findViewById(R.id.rect);  
      
rect.setOnClickListener(new View.OnClickListener() {  
        @Override  
        public void onClick(View v) {  
            Animator animator = ViewAnimationUtils.createCircularReveal(  
                    rect,0,0,0,(float) Math.hypot(rect.getWidth(), rect.getHeight()));  
            animator.setInterpolator(new AccelerateInterpolator());  
            animator.setDuration(2000);  
            animator.start();  
        }  
});

顯示效果:

 wKiom1f6eebz3kCDAAEk_72R9Xk661.gif



 3. Activity Transition


   1) 什麼是Transition?

   安卓5.0中Activity和Fragment 變換是建立在名叫Transitions的安卓新特性之上的。這個誕生於4.4的transition框架爲在不同的UI狀態之間產生動畫效果提供了非常方便的API。該框架主要基於兩個概念:場景(scenes)和變換(transitions)。場景(scenes)定義了當前的UI狀態,變換(transitions)則定義了在不同場景之間動畫變化的過程。雖然transition翻譯爲變換似乎很確切,但是總覺得還是沒有直接使用transition直觀,爲了更好的理解下面個別地方直接用transition代表變換。


   當一個場景改變的時候,transition主要負責:

  (1)捕捉每個View在開始場景和結束場景時的狀態。

  (2)根據兩個場景(開始和結束)之間的區別創建一個Animator。


   2) Android 5.0(API 級別 21)支持這些進入與退出轉換:

     (1)分解 - 從場景中心移入或移出視圖。

     (2)滑動 - 從場景邊緣移入或移出視圖。

     (3)淡入淡出 - 通過調整透明度在場景中增添或移除視圖。


   3)Android 5.0(API 級別 21)也支持這些共享元素轉換:

     (1)changeBounds - 爲目標視圖的佈局邊界的變化添加動畫。

     (2) changeClipBounds - 爲目標視圖的裁剪邊界的變化添加動畫。

     (3)changeTransform - 爲目標視圖的縮放與旋轉變化添加動畫。

     (4)changeImageTransform - 爲目標圖像的大小與縮放變化添加動畫。


   4) 實現方式:

     (1). xml 實現方式:

      res/transition/activity_fade.xml

<?xml version="1.0" encoding="utf-8"?>
<fade xmlns:android="http://schemas.android.com/apk/res/"
android:duration="1000"/>
res/transition/activity_slide.xml
<?xml version="1.0" encoding="utf-8"?>
<slide xmlns:android="http://schemas.android.com/apk/res/"
android:duration="1000"/>

    MainActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
    }
 
    private void setupWindowAnimations() {
Slide slide = TransitionInflater.from(this).inflateTransition(R.transition.activity_slide);
getWindow().setExitTransition(slide);
}
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
}
private void setupWindowAnimations() {
        Fade fade = TransitionInflater.from(this).inflateTransition(R.transition.activity_fade);
        getWindow().setEnterTransition(fade);
    }

 

    (2)代碼實現方式:

     MainActivity.java

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
    }
    private void setupWindowAnimations() {
        Slide slide = new Slide();
        slide.setDuration(1000);
        getWindow().setExitTransition(slide);
    }

     TransitionActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
    }
 
    private void setupWindowAnimations() {
        Fade fade = new Fade();
        fade.setDuration(1000);
        getWindow().setEnterTransition(fade);
    }


實例代碼:


   (1). Styles文件 :

  <resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item> <!--設置選中的顏色-->
        <!-- 允許使用transitions -->
        <item name="android:windowContentTransitions">true</item>
        <!--是否覆蓋執行,其實可以理解成是否同步執行還是順序執行-->
        <item name="android:windowAllowEnterTransitionOverlap">false</item>
        <item name="android:windowAllowReturnTransitionOverlap">false</item>
    </style>
</resources>



   (2). MainActivity部分代碼:

 @Override
    public void onClick(View v) {
        ArrayList<Pair<View,String>> arrayList = new ArrayList<Pair<View,String>>();
        switch (v.getId()) {
            case R.id.explode_btn:
                setExplodeTransition();
                flag = AnimConstant.EXPLODE_FLAG;
                break;
            case R.id.slide_btn:
                setSlideTransition();
                flag = AnimConstant.SLIDE_FLAG;
                break;
            case R.id.pade_in_out_btn:
                setFadeTransition();
                flag = AnimConstant.PADE_IN_OUT_FLAG;
                break;
            case R.id.shared_element_btn:
                arrayList.add(new Pair<View, String>(shareElementBtn, "shared_name_btn"));
                flag = AnimConstant.SHARED_ELEMENTS_FLAG;
                break;
        }
        startActivity(arrayList);
    }
    private void setFadeTransition() {
        Fade fadeTransition = new Fade();
        fadeTransition.setDuration(1000);
        getWindow().setReenterTransition(fadeTransition);
        getWindow().setExitTransition(fadeTransition);
    }
 
    private void startActivity(ArrayList<Pair<View, String>> arrayList) {
        Intent intent = new Intent();
        intent.setClass(this ,SecondActivity.class);
        intent.putExtra("transition_flag",flag);
        ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, arrayList.toArray(new Pair[arrayList.size()]));
        startActivity(intent, options.toBundle());
    }
   private void setExplodeTransition() {
        Explode explode = new Explode();
        explode.setDuration(2000);
        getWindow().setReenterTransition(explode);
        getWindow().setExitTransition(explode);
    }
    private void setSlideTransition() {
        Slide slideTransition = new Slide();
        slideTransition.setSlideEdge(Gravity.LEFT);
        slideTransition.setDuration(1000);
        getWindow().setReenterTransition(slideTransition);
        getWindow().setExitTransition(slideTransition);
}

  (3) SecondActivity類:

  private Button returnBtn = null;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Intent intent = getIntent();
        int flag = intent.getIntExtra("transition_flag" ,-1);
        if (flag != AnimConstant.SHARED_ELEMENTS_FLAG) {
            setupWindowAnimations();
        }
        returnBtn = (Button) this.findViewById(R.id.return_btn);
        returnBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finishAfterTransition();
            }
        });
    }
 
    private void setupWindowAnimations() {
        Explode explode = new Explode();
        explode.setDuration(2000);
        getWindow().setEnterTransition(explode);
    }

顯示效果:

wKiom1f6fUmQRGxEAAuLmgoJFJQ552.gif

   4.Curved motion

              Material design中的動畫利用曲線實現時間內插與空間移動模式。 在 Android 5.0API 級別 21)及更高版本,您可爲動畫定義定製時間曲線以及曲線運動模式。PathInterpolator 類別是一個基於貝塞爾曲線或 Path 對象的全新插入器。 此插入器在一個 1x1 的正方形內指定一個運動曲線,定位點位於 (0,0) 以及 (1,1),而控制點則使用構造函數參數指定。 

有兩種定義PathInterpolator的方法:

 第一種XML方式:

<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:controlX1="0.4"
    android:controlY1="0"
    android:controlX2="1"
    android:controlY2="1"/>


系統將爲材料設計規範中的三種基本曲線提供 XML 資源:

@interpolator/fast_out_linear_in.xml

@interpolator/fast_out_slow_in.xml

@interpolator/linear_out_slow_in.xml


第二種代碼實現

public class SCPahtInterpolator extends PathInterpolator {
    public static final float DEFALUT_CONTROL_1_X = 0.5f;
    public static final float DEFALUT_CONTROL_1_Y = 0f;
    public static final float DEFALUT_CONTROL_2_X = 0f;
    public static final float DEFALUT_CONTROL_2_Y = 1f;
    public SCPahtInterpolator() {
        super(DEFALUT_CONTROL_1_X, DEFALUT_CONTROL_1_Y, DEFALUT_CONTROL_2_X, DEFALUT_CONTROL_2_Y);
    }
    public SCPahtInterpolator(Path path) {
        super(path);
    }
    public SCPahtInterpolator(float controlX, float controlY) {
        super(controlX, controlY);
    }
    public SCPahtInterpolator(float controlX1, float controlY1, float controlX2, float controlY2) {
        super(controlX1, controlY1, controlX2, controlY2);
    }
    public SCPahtInterpolator(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

可用Animator.setInterpolator()設置PathInterpolator

ObjectAnimator 類別擁有新的構造函數,可讓您一次使用兩個或更多屬性在路徑上爲座標添加動畫。 例如,下列動畫使用 Path 對象爲視圖的 X 和 Y 屬性添加動畫:

ObjectAnimator mAnimator;
mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
...
mAnimator.start();


   5.視圖狀態改變

   StateListAnimator 類別讓您能夠定義視圖狀態改變時運行的動畫。 下列示例顯示如何將 StateListAnimator 定義爲一個 XML 資源:

<!-- animate the translationZ property of a view when pressed -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true">
    <set>
      <objectAnimator android:propertyName="translationZ"
        android:duration="@android:integer/config_shortAnimTime"
        android:valueTo="2dp"
        android:valueType="floatType"/>
        <!-- you could have other objectAnimator elements
             here for "x" and "y", or other properties -->
    </set>
  </item>
  <item android:state_enabled="true"
    android:state_pressed="false"
    android:state_focused="true">
    <set>
      <objectAnimator android:propertyName="translationZ"
        android:duration="100"
        android:valueTo="0"
        android:valueType="floatType"/>
    </set>
  </item>
</selector>


如果要將定製視圖狀態動畫附加至一個視圖,請依照此示例使用 XML 資源文件中的 selector 元素定義一個動畫,並使用 android:stateListAnimator屬性將此動畫分配給您的視圖。 如果要將一個狀態列表動畫分配給您的代碼內的一個視圖,請使用 AnimationInflater.loadStateListAnimator() 方法,並以 View.setStateListAnimator() 方法將動畫分配給您的視圖。

當您的主題擴展材料主題時,在默認情況下按鈕將擁有一個 Z 動畫。如果要避免您的按鈕出現這類行爲,請將 android:stateListAnimator 屬性設置爲@null。

AnimatedStateListDrawable 類別讓您能夠創建圖片,顯示相關視圖之間的狀態變化。 Android 5.0 中的某些系統小組件在默認情況下使用這些動畫。 下列示例顯示如何將 AnimatedStateListDrawable 定義爲一個 XML 資源:

<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
    xmlns:android="http://schemas.android.com/apk/res/android">
 
    <!-- provide a different drawable for each state-->
    <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
        android:state_pressed="true"/>
    <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
        android:state_focused="true"/>
    <item android:id="@id/default"
        android:drawable="@drawable/drawableD"/>
 
    <!-- specify a transition -->
    <transition android:fromId="@+id/default" android:toId="@+id/pressed">
        <animation-list>
            <item android:duration="15" android:drawable="@drawable/dt1"/>
            <item android:duration="15" android:drawable="@drawable/dt2"/>
            ...
        </animation-list>
    </transition>
    ...
</animated-selector>


 

   6.爲矢量圖片添加動畫

   矢量圖片可在不丟失定義的情況下縮放。 AnimatedVectorDrawable 類別可讓您爲矢量圖片的屬性添加動畫。

您通常可以在 3 個 XML 文件中定義添加動畫的矢量圖片:

在 res/drawable/ 中擁有 <vector> 元素的矢量圖片

在 res/drawable/ 中擁有 <animated-vector> 元素且已添加動畫的矢量圖片

在 res/anim/ 中擁有 <objectAnimator> 元素的一個或多個對象動畫

添加動畫的矢量圖片可爲 <group> 以及 <path> 元素的屬性添加動畫。<group> 元素定義路徑集或子組,而 <path> 元素則定義將繪製的路徑。

當您定義一個您想要添加動畫的矢量圖片時,請使用 android:name 屬性給這些羣組和路徑指定一個唯一名稱,以便讓您能夠從您的動畫定義中引用這些羣組或路徑。 例如:

<!-- res/drawable/vectordrawable.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600">
    <group
        android:name="rotationGroup"
        android:pivotX="300.0"
        android:pivotY="300.0"
        android:rotation="45.0" >
        <path
            android:name="v"
            android:fillColor="#000000"
            android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
    </group>
</vector>

已添加動畫的矢量圖片定義按名稱引用矢量圖片內的羣組和路徑:

<!-- res/drawable/animvectordrawable.xml -->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:drawable="@drawable/vectordrawable" >
    <target
        android:name="rotationGroup"
        android:animation="@anim/rotation" />
    <target
        android:name="v"
        android:animation="@anim/path_morph" />
</animated-vector>


動畫定義代表着 ObjectAnimator 或 AnimatorSet 對象。此示例中的第一個動畫將目標羣組旋轉 360 度:

<!-- res/anim/rotation.xml -->
<objectAnimator
    android:duration="6000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />


此示例中的第二個動畫對矢量圖片的路徑進行變形。 兩個路徑均需可兼容變形操作:兩個路徑均需擁有相同數量的指令,而且每個指令均需擁有相同數量的參數。


<!-- res/anim/path_morph.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="3000"
        android:propertyName="pathData"
        android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"
        android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"
        android:valueType="pathType" />
</set>



引用的文章:

   http://www.open-open.com/lib/view/open1416663769680.html

   http://blog.csdn.net/feng88724/article/details/6318430

   http://www.lightskystreet.com/2015/05/23/anim_basic_knowledge/



  



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章