Android 動畫(View動畫,幀動畫,屬性動畫)詳細介紹_Android

來源:互聯網
上載者:User

0. 前言 

Android動畫是面試的時候經常被問到的話題。我們都知道Android動畫分為三類:View動畫、幀動畫和屬性動畫。

先對這三種動畫做一個概述:

View動畫是一種漸進式動畫,通過映像的平移、縮放、旋轉和透明度等各種漸進式變換完成動畫效果。

幀動畫是通過不停的切換圖片實現動畫效果。

屬性動畫是不停的改變對象的屬性來實現動畫效果。本文原創,轉載請註明出處:

http://blog.csdn.net/seu_calvin/article/details/52724655

1.  View動畫 

1.1  系統提供的四種View動畫(補間動畫)

View動畫可以在res/anim/name.xml檔案裡進行配置,四種View動畫的漸層式變換分別對應<translate>、<scale>、<rotate>、<alpha>四個標籤,動畫集合可以使用<set>標籤。xml的各個動畫屬性比較簡單,這裡就不再貼執行個體代碼了。只需要注意如何應用配置好的xml檔案來啟動動畫即可:

view.startAnimation(AnimationUtils.loadAnimation(this,R.anim.myanimation)); 

這些當然也可以在Java代碼裡進行配置,也比較簡單,這裡寫了一個範例程式碼:

splash = (RelativeLayout)findViewById(R.id.splash); //旋轉動畫 RotateAnimation rotateAnimation = new RotateAnimation(0,360,         Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); rotateAnimation.setDuration(2000); rotateAnimation.setFillAfter(true); //縮放動畫 ScaleAnimation scaleAnimation = new ScaleAnimation(0,1,0,1,         Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); scaleAnimation.setDuration(2000); scaleAnimation.setFillAfter(true); //漸層動畫 AlphaAnimation alphaAnimation = new AlphaAnimation(0.2f,1.0f); alphaAnimation.setDuration(2000); alphaAnimation.setFillAfter(true); //平移動畫 TranslateAnimation translateAnimation = newTranslateAnimation (0,0,100,100); translateAnimation.setDuration(2000); translateAnimation.setFillAfter(true); //動畫集合 AnimationSet animationSet = new AnimationSet(true); animationSet.addAnimation(rotateAnimation); animationSet.addAnimation(scaleAnimation); animationSet.addAnimation(alphaAnimation); animationSet.addAnimation(translateAnimation); //啟動動畫 plash.startAnimation(animationSet); 

1.2   自訂View動畫

自訂動畫實際應用中比較少見,因此這裡只做簡單介紹。

完成自訂動畫需要繼承Animation類,並重寫其initialize()以及applyTransformation()。

前者用於一些初始化的操作,後者用於進行矩陣變換。

1.3     為ViewGroup的所有子項目設定動畫

上面1.1,1.2都是給View設定動畫效果,Android同樣提供了為ViewGroup設定

android:layoutAnimation=”@anim/layout_anim”來達到給ViewGroup中所有子項目設定動畫的目的。下面給出相關代碼:

//res/anim/anim/layout_anim.xml <layoutAnimation xmlns:android=” http://schemas.android.com/apk/res/android” android:delay=”0.1” //動畫延遲時間為0.1*T,本例為100ms android:animationOrder=”normal” //子項目的播放動畫順序為順序,也有reverse以及random android: animation=” @anim/layout_anim_item”/>  //res/anim/anim/layout_anim_item.xml <?xml version=”1.0” encoding=”utf-8”?> <set xmlns:android=”http://schemas.android.com/apk/res/android”  animation:duration=”200” //每個子項目的動畫周期T  animation:interpolator=”@android:anim/accelerate_ interpolator” //指定插值器 animation:shareInterpolator=”true”> //表示所有子項目共用該插值器 <alpha android:fromAlpha=”0.2” android: toAlpha =”1.0”/> <translate android:fromXDelta=”100” android: toXDelta =”0”/> </set> 

1.4     為Activity切換設定動畫

估計大家也都用過,在startActivity()之後使用,使Activity切換時達到一個平移的動畫效果:

overridePendingTransition(R.anim.tran_in,R.anim.tran_out); 

//res/anim/tran_in <?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" //表示從螢幕100%的位置開始,因此tran_out當然是toXDelta="-100%p",其他不變 android:fromXDelta="100%p" android:fromYDelta="0"   android:toXDelta="0"   android:toYDelta="0" > </translate> 

2.   幀動畫

上面也提到了,幀動畫就是不停的切換圖片實現動畫效果。很明顯容易OOM,所以使用幀動畫要注意圖片大小。
幀動畫的使用也很簡單,使用樣本如下:

//res/drawable/myanimation.xml <?xml version=”1.0” encoding=”utf-8”?> <animation-list xmlns:android=”http://schemas.android.com/apk/res/android”  animation:oneshot=”false” > //false為迴圈播放,true為類似於View動畫的setFillAfter效果 <item android: drawable =”@ drawable/ drawable 1” android:duration=” 200”> <item android: drawable =”@ drawable/ drawable 2” android:duration=” 200”> </animation-list>  //在代碼裡載入動畫設定並啟動動畫 view.setBackgroundResource(R.drawable.myanimation.xml); (AnimationDrawable)view.getBackground.start(); 

3.   屬性動畫

View動畫的那四種效果有很明顯的缺點,繪製出來的效果其實並沒有真正改變View的屬性,即left、top、right和bottom的值,只是系統臨時繪製的結果。這樣View的點擊位置並沒有發生變化。針對這個問題,從Android3.0開始屬性動畫應運而生。

屬性動畫本質是通過改變新增的屬性(如平移translationX/Y、縮放scaleX/Y、旋轉rotationX/Y等)並重新整理螢幕來實現動畫效果,並且實現點擊位置的即時改變。但是屬性動畫仍然不會修改原始的上下左右四個值。最後需要注意的是,屬性動畫不止用於View,還可以用於任何對象。

下面介紹與屬性動畫相關的類和方法:

3.1  setTranslationX方法

該方法直接更改view屬性的方法,因為有時候不需要使用動畫效果。

view.setTranslationX(x);//3.0以後 ViewHelper.setTranslationX(view,x);//3.0以前通過NineOldAndroid庫實現 

3.2   ValueAnimator類

ValueAnimator只定義和執行動畫流程,並沒有直接操作屬性值的邏輯,需要添加動畫更新的監聽,並在onAnimationUpdate()中執行自訂的動畫邏輯。[java] view plain copy 在CODE上查看代碼片派生到My Code片ValueAnimator animator = ValueAnimator.ofInt(1, 100); //定義動畫,相當於1秒內數100個數 animator.addUpdateListener(new AnimatorUpdateListener() {   @Override   public void onAnimationUpdate(ValueAnimator animation){     float fraction = animation.getAnimatedFraction();//動畫進度值0-1     //整型估值器幫我們計算了start+(end-strat)*fraction,並設定給控制項的寬度     view.getLayoutParams().width = new IntEvaluator().evaluate(fraction,start,end) //不需要set方法     view.requestLayout();   } }); animator.setDuration(1000).start(); 

3.3    ObjectAnimator類

ObjectAnimator繼承自ValueAnimator,它允許直接改變view的屬性,下面通過一個例子介紹。

//x軸方向縮放的例子 ObjectAnimator animator = ObjectAnimator.ofFloat(view,”scaleX”,2.0f); animator.setDuration(1000); animator.setStartDelay(1000); animator.start(); 

大多數的情況使用ObjectAnimator就足夠了,因為它不用像ValueAnimator那樣自己寫動畫更新的邏輯,但是ObjectAnimator有一定的限制——它需要目標屬性提供指定的處理方法(譬如提供get/set方法),這是因為ObjectAnimator的原理是不停的調用set方法更新屬性值,並且如果我們沒有傳遞初始值,系統會直接調用get方法擷取值。而上面3.2中介紹過的ValueAnimator則不直接操作屬性值,所以要操作對象的屬性可以不需要se/get方法,你完全可以通過當前動畫的計算去修改任何屬性。

針對這個問題,官方推薦我們用一個類封裝原始對象,間接為其提供get/set方法,實現起來很簡單,執行個體如下:

ViewWrapper wrapper = new ViewWrapper(view); ObjectAnimator.ofInt(view,”width”,200).setDuration(1000).start();  private static class ViewWrapper{   private View myView;  public ViewWrapper(View view){   myView = view;  }  public int getWidth(){   return myView.getLayoutParams().width;  }  public int setWidth(int width){  myView.getLayoutParams().width = width;  myView.requestLayout();  } } 

3.4  ViewPropertyAnimation類

ViewPropertyAnimation是NineOldAndroid庫中的類,簡化了ObjectAnimator類的操作,並且NineOldAndroid庫相容了3.0以前的Android版本。下面經過一個例子介紹。

//x軸方向縮放的例子,效果同3.3 ViewPropertyAnimation.animate(view).scaleX(2.0f).setDuration(1000) .setInterpolator(new OvershootInterpolator()) .setStartDelay(1000).start(); 

3.5  AnimationSet類

動畫集合,提供把多個動畫組合成一個組合的機制,並可設定動畫的時序關係,如同時播放、順序播放或延遲播放。具體使用方法比較簡單,如下所示:

ObjectAnimator objectAnimator1= ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0f);  ObjectAnimator objectAnimator2= ObjectAnimator.ofFloat(view, "translationY", 0f, 30f);  ObjectAnimator objectAnimator3= ObjectAnimator.ofFloat(view, "translationX", 0f, 30f);  AnimatorSet animatorSet = new AnimatorSet();  animatorSet.setDuration(5000);  animatorSet.setInterpolator(new LinearInterpolator());   // animatorSet.playTogether(objectAnimator1, objectAnimator2. objectAnimator3); //三個動畫同時執行  // 12同時執行,3接著執行  animatorSet.play(objectAnimator1).with(objectAnimator2);  animatorSet.play(objectAnimator3).after(objectAnimator2);  animatorSet.start(); 

4.  插值器總結

4.1  系統已經提供給我們的插值器
各種插值器都是實現了Interpolator介面,下面來看一下系統已經提供給我們直接使用的插值器。

 4.2  自訂插值器

Interpolator都實現了Interpolator介面,而Interpolator介面又繼承自TimeInterpolator,TimeInterpolator介面定義了一個由系統調用的getInterpolation(float input)方法,其中參數input代表動畫完成進度,在0和1之間。我們自訂插值器只需要實現Interpolator介面並覆寫getInterpolation()方法即可實現自訂的動畫效果。 

如下就是一個動畫始末速率較慢、中間加速的AccelerateDecelerateInterpolator插值器:

public class AccelerateDecelerateInterpolator extends BaseInterpolator     implements NativeInterpolatorFactory {   ......   public float getInterpolation(float input) {     return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;   }   ...... } 

5.  動畫監聽器

我們在平時開發過程中,經常要監聽動畫完成的時機以繼續商務邏輯,那麼我們可以通過給動畫集合設定AnimationListener監聽器來實現。分別可以監聽動畫開始、結束、取消以及重複播放。

//監聽動畫完成 animationSet.setAnimationListener(new Animation.AnimationListener() {   @Override   public void onAnimationStart(Animation animation) {}   @Override   public void onAnimationEnd(Animation animation) {}   @Override public void onAnimationRepeat(Animation animation) {} @Override   public void onAnimationCancel(Animation animation) {} }); 

最後若想監聽動畫中每一幀的回調,我們可以設定AnimatorUpdateListener監聽器並重寫其onAnimationUpdate()方法即可。

至此關於Android動畫的知識總結完畢。

感謝閱讀,希望能協助到大家,謝謝大家對本站的支援!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.