什麼是動畫,動畫的本質是經過接二連三地顯示若干圖像來產生「動」起來的效果。好比說一個移動的動畫,就是在必定的時間段內,以恰當的速率(起碼要12幀/秒以上,纔會讓人產生動起來的錯覺)每隔若干時間在屏幕上更新一次位置。遊戲中的動畫效果也是由此而來。一樣還有其餘屬性變動所引發的動畫效果,從數學的角度來看,包括:(1)平移(2)旋轉(3)縮放(4)透明度。固然這些屬性能夠組合起來使用,來達到更絢麗的畫面。可是不論什麼樣的組合方式,咱們均可以統一用Matirx運算來實現,從技術實現的角度來說,Matrix是動畫的核心,2D不用說,3D更是依賴矩陣(Matrix)的運算。固然,今天只是講講怎麼實現動畫效果,不會涉及這些基礎知識~~html
1、Tween Animation(補間動畫)java
補間動畫能夠實現View組件的移動、放大、縮小以及漸變等效果。也是咱們使用動畫效果時最經常使用的動畫了。android
一共有四種動畫,分別爲git
AlphaAnimation |
漸變透明度動畫效果 |
ScaleAnimation |
漸變尺寸伸縮動畫效果 |
TranslateAnimation |
畫面轉換位置移動動畫效果 |
RotateAnimation |
畫面轉移旋轉動畫效果 |
而設置動畫也有兩種方式,一種是在代碼中設置,另外一種就是在xml文件中配置。github
public Animation AlphaAnimation(){ Animation myAnimation_Alpha; //透明度從0到1 myAnimation_Alpha = new AlphaAnimation(0,1); //設置時間持續時間爲 2000毫秒 myAnimation_Alpha.setDuration(2000); return myAnimation_Alpha; }
很簡單,新建一個AlphaAnimation的類,裏面放着要變化的起始參數和結束參數,而後程序就會自動演化出過場的動畫。最後在要動畫的view上設置
canvas
myAnimation = AlphaAnimation();
av.startAnimation(myAnimation);//av是一個imageview
public Animation RotateAnimation(){ Animation myAnimation_Rotate; //第一個參數fromDegrees爲動畫起始時的旋轉角度 //第二個參數toDegrees爲動畫旋轉到的角度 //第三個參數pivotXType爲動畫在X軸相對於物件位置類型 //第四個參數pivotXValue爲動畫相對於物件的X座標的開始位置 //第五個參數pivotXType爲動畫在Y軸相對於物件位置類型 //第六個參數pivotYValue爲動畫相對於物件的Y座標的開始位置 myAnimation_Rotate = new RotateAnimation(0.0f, +350.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f); //動畫插入器,能夠本身定義動畫的速度 //加速-減速 動畫插入器 myAnimation_Rotate.setInterpolator(this,android.R.anim.accelerate_decelerate_interpolator); myAnimation_Rotate.setDuration(2000); return myAnimation_Rotate; }
裏面有一個動畫插入器的概念,這是控制動畫過程速度的一個方法,好比上面代碼中的accelerate_decelerate_interpolator就是要求動畫先加速運行,在減速運行api
public Animation TranslateAnimation(){ //TranslateAnimation(float fromXDelta, float toXDelta, //float fromYDelta, float toYDelta) //第一個參數fromXDelta爲動畫起始時 X座標上的移動位置 //第二個參數toXDelta爲動畫結束時 X座標上的移動位置 //第三個參數fromYDelta爲動畫起始時Y座標上的移動位置 //第四個參數toYDelta爲動畫結束時Y座標上的移動位置 Animation myAnimation_Translate; myAnimation_Translate=new TranslateAnimation(0.0f, -80.0f, 0.0f, 300.0f); myAnimation_Translate.setDuration(2000); myAnimation_Translate.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { av.setTranslationX(av.getTranslationX()-80f); av.setTranslationY(av.getTranslationY()+300f); } @Override public void onAnimationRepeat(Animation animation) { } }); return myAnimation_Translate; }
public Animation ScaleAnimation(){ Animation myAnimation_Scale; //第一個參數fromX爲動畫起始時 X座標上的伸縮尺寸 //第二個參數toX爲動畫結束時 X座標上的伸縮尺寸 //第三個參數fromY爲動畫起始時Y座標上的伸縮尺寸 //第四個參數toY爲動畫結束時Y座標上的伸縮尺寸 /*說明: 以上四種屬性值 0.0表示收縮到沒有 1.0表示正常無伸縮 值小於1.0表示收縮 值大於1.0表示放大 */ //第五個參數pivotXType爲動畫在X軸相對於物件位置類型 //第六個參數pivotXValue爲動畫相對於物件的X座標的開始位置 //第七個參數pivotXType爲動畫在Y軸相對於物件位置類型 //第八個參數pivotYValue爲動畫相對於物件的Y座標的開始位置 /*myAnimation_Scale = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f); myAnimation_Scale.setDuration(2000);*/ //使用xml讀取動畫 myAnimation_Scale = AnimationUtils.loadAnimation(this,R.anim.scale); return myAnimation_Scale; }
這裏咱們使用讀取anim文件夾下的xml文件來設置動畫(若res文件夾下沒有anim文件夾要本身建立)
xml內部內容以下:
數組
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:interpolator= "@android:anim/accelerate_decelerate_interpolator" android:fromXScale="0.0" android:toXScale="1.4" android:fromYScale="0.0" android:toYScale="1.4" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> </set> <!-- 尺寸伸縮動畫效果 scale 屬性:interpolator 指定一個動畫的插入器 在我試驗過程當中,使用android.res.anim中的資源時候發現 有三種動畫插入器: accelerate_decelerate_interpolator 加速-減速 動畫插入器 accelerate_interpolator 加速-動畫插入器 decelerate_interpolator 減速- 動畫插入器 其餘的屬於特定的動畫效果 浮點型值: fromXScale 屬性爲動畫起始時 X座標上的伸縮尺寸 toXScale 屬性爲動畫結束時 X座標上的伸縮尺寸 fromYScale 屬性爲動畫起始時Y座標上的伸縮尺寸 toYScale 屬性爲動畫結束時Y座標上的伸縮尺寸 說明: 以上四種屬性值 0.0表示收縮到沒有 1.0表示正常無伸縮 值小於1.0表示收縮 值大於1.0表示放大 pivotX 屬性爲動畫相對於物件的X座標的開始位置 pivotY 屬性爲動畫相對於物件的Y座標的開始位置 說明: 以上兩個屬性值 從0%-100%中取值 50%爲物件的X或Y方向座標上的中點位置 長整型值: duration 屬性爲動畫持續時間 說明: 時間以毫秒爲單位 布爾型值: fillAfter 屬性 當設置爲true ,該動畫轉化在動畫結束後被應用 -->
scale的參數可能有點多,其實也就是比Translate的動畫多了設置中心點的參數,其餘跟Translate相似,只不過scale是對x,y進行縮放而不是位移
app
private AnimationSet mySet = new AnimationSet(true); public void AllAnimation(){ mySet.addAnimation(AlphaAnimation()); mySet.addAnimation(RotateAnimation()); mySet.addAnimation(TranslateAnimation()); mySet.addAnimation(ScaleAnimation()); mySet.setDuration(3000); av.startAnimation(mySet); }
動畫集合能夠將多個動畫放到一個集合中,而後一塊兒進行播放。(AnimationSet也是繼承自Animation類,因此其它的屬性跟單個動畫差很少)框架
public class MyActivity extends Activity implements View.OnClickListener { private ImageView av; private Button alpha,rotate,translate,scale; private AnimationSet mySet; private Button allAnimation,back; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); mySet = new AnimationSet(true); av = (ImageView)findViewById(R.id.imageView2); alpha = (Button)findViewById(R.id.alpha); alpha.setOnClickListener(this); rotate = (Button)findViewById(R.id.rotate); rotate.setOnClickListener(this); translate = (Button)findViewById(R.id.translate); translate.setOnClickListener(this); scale = (Button)findViewById(R.id.scale); scale.setOnClickListener(this); allAnimation = (Button)findViewById(R.id.all); allAnimation.setOnClickListener(this); back = (Button)findViewById(R.id.back); back.setOnClickListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.my, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } @Override public void onClick(View v) { Animation myAnimation = null; switch(v.getId()){ case R.id.alpha: myAnimation = AlphaAnimation(); av.startAnimation(myAnimation);//av是一個imageview break; case R.id.rotate: myAnimation = RotateAnimation(); av.startAnimation(myAnimation); break; case R.id.translate: myAnimation = TranslateAnimation(); av.startAnimation(myAnimation); break; case R.id.scale: myAnimation = ScaleAnimation(); av.startAnimation(myAnimation); break; case R.id.all: AllAnimation(); break; case R.id.back: this.finish(); break; } } public Animation AlphaAnimation(){ Animation myAnimation_Alpha; //透明度從0到1 myAnimation_Alpha = new AlphaAnimation(0,1); //設置時間持續時間爲 2000毫秒 myAnimation_Alpha.setDuration(2000); return myAnimation_Alpha; } public Animation RotateAnimation(){ Animation myAnimation_Rotate; //第一個參數fromDegrees爲動畫起始時的旋轉角度 //第二個參數toDegrees爲動畫旋轉到的角度 //第三個參數pivotXType爲動畫在X軸相對於物件位置類型 //第四個參數pivotXValue爲動畫相對於物件的X座標的開始位置 //第五個參數pivotXType爲動畫在Y軸相對於物件位置類型 //第六個參數pivotYValue爲動畫相對於物件的Y座標的開始位置 myAnimation_Rotate = new RotateAnimation(0.0f, +350.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f); //動畫插入器,能夠本身定義動畫的速度 //加速-減速 動畫插入器 myAnimation_Rotate.setInterpolator(this,android.R.anim.accelerate_decelerate_interpolator); myAnimation_Rotate.setDuration(2000); return myAnimation_Rotate; } public Animation TranslateAnimation(){ //TranslateAnimation(float fromXDelta, float toXDelta, //float fromYDelta, float toYDelta) //第一個參數fromXDelta爲動畫起始時 X座標上的移動位置 //第二個參數toXDelta爲動畫結束時 X座標上的移動位置 //第三個參數fromYDelta爲動畫起始時Y座標上的移動位置 //第四個參數toYDelta爲動畫結束時Y座標上的移動位置 Animation myAnimation_Translate; myAnimation_Translate=new TranslateAnimation(0.0f, -80.0f, 0.0f, 300.0f); myAnimation_Translate.setDuration(2000); myAnimation_Translate.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { av.setTranslationX(av.getTranslationX()-80f); av.setTranslationY(av.getTranslationY()+300f); } @Override public void onAnimationRepeat(Animation animation) { } }); return myAnimation_Translate; } public Animation ScaleAnimation(){ Animation myAnimation_Scale; //第一個參數fromX爲動畫起始時 X座標上的伸縮尺寸 //第二個參數toX爲動畫結束時 X座標上的伸縮尺寸 //第三個參數fromY爲動畫起始時Y座標上的伸縮尺寸 //第四個參數toY爲動畫結束時Y座標上的伸縮尺寸 /*說明: 以上四種屬性值 0.0表示收縮到沒有 1.0表示正常無伸縮 值小於1.0表示收縮 值大於1.0表示放大 */ //第五個參數pivotXType爲動畫在X軸相對於物件位置類型 //第六個參數pivotXValue爲動畫相對於物件的X座標的開始位置 //第七個參數pivotXType爲動畫在Y軸相對於物件位置類型 //第八個參數pivotYValue爲動畫相對於物件的Y座標的開始位置 /*myAnimation_Scale = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f); myAnimation_Scale.setDuration(2000);*/ //使用xml讀取動畫 myAnimation_Scale = AnimationUtils.loadAnimation(this,R.anim.scale); return myAnimation_Scale; } public void AllAnimation(){ mySet.addAnimation(AlphaAnimation()); mySet.addAnimation(RotateAnimation()); mySet.addAnimation(TranslateAnimation()); mySet.addAnimation(ScaleAnimation()); mySet.setDuration(3000); av.startAnimation(mySet); } }
2、Frame Animation(逐幀動畫)
所謂的逐幀動畫就是日常咱們觀看的視頻同樣,都是一幀一幀的快速播放圖片來欺騙觀衆的眼球以達到動起來的錯覺。
<?xml version="1.0" encoding="utf-8"?> <!-- animation-list是一組圖片的數組,用來逐幀顯示 --> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false" ><!-- oneshot表示是否只循環一遍 --> <item android:drawable="@drawable/p0" android:duration="500" /> <item android:drawable="@drawable/p1" android:duration="500" /> <item android:drawable="@drawable/p2" android:duration="500" /> <item android:drawable="@drawable/p3" android:duration="500" /> <item android:drawable="@drawable/p4" android:duration="500" /> <item android:drawable="@drawable/p5" android:duration="500" /> </animation-list>
上面每一個item就是一張圖片,這個xml文件要放在drawable文件夾中。
在代碼中調用
iv.setBackgroundResource(R.drawable.frame_animation); AnimationDrawable anim = (AnimationDrawable) iv.getBackground(); anim.start();
iv是一個ImageView控件,設置背景圖像後,就能夠開始動畫。
//徹底編碼實現的動畫效果 AnimationDrawable anim = new AnimationDrawable(); for (int i = 1; i <= 4; i++) { //根據資源名稱和目錄獲取R.java中對應的資源ID int id = getResources().getIdentifier("p" + i, "drawable", getPackageName()); //根據資源ID獲取到Drawable對象 Drawable drawable = getResources().getDrawable(id); //將此幀添加到AnimationDrawable中 anim.addFrame(drawable, 500); } anim.setOneShot(false); //設置爲loop //api15之前 iv.setBackgroundDrawable(anim); //將動畫設置爲ImageView背景 //api16之後 //iv.setBackground(anim); anim.start(); //開始動畫
package com.cpacm.demo.testrep; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.ImageView; import com.cpacm.demo.testrep.R; public class FrameAnimationActivity extends Activity implements View.OnClickListener{ private ImageView iv; private Button b1,b2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_frame_animation); iv = (ImageView)findViewById(R.id.imageView); b1 = (Button)findViewById(R.id.start); b1.setOnClickListener(this); b2 = (Button)findViewById(R.id.end); b2.setOnClickListener(this); } @Override public void onClick(View v) { switch(v.getId()){ case R.id.start: iv.setBackgroundResource(R.drawable.frame_animation); AnimationDrawable anim = (AnimationDrawable) iv.getBackground(); anim.start(); //runFrame(); break; case R.id.end: AnimationDrawable anim2 = (AnimationDrawable) iv.getBackground(); if (anim2.isRunning()) { //若是正在運行,就中止 anim2.stop(); } break; } } public void runFrame() { //徹底編碼實現的動畫效果 AnimationDrawable anim = new AnimationDrawable(); for (int i = 1; i <= 4; i++) { //根據資源名稱和目錄獲取R.java中對應的資源ID int id = getResources().getIdentifier("p" + i, "drawable", getPackageName()); //根據資源ID獲取到Drawable對象 Drawable drawable = getResources().getDrawable(id); //將此幀添加到AnimationDrawable中 anim.addFrame(drawable, 500); } anim.setOneShot(false); //設置爲loop //api15之前 iv.setBackgroundDrawable(anim); //將動畫設置爲ImageView背景 //api16之後 //iv.setBackground(anim); anim.start(); //開始動畫 } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.frame_animation, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
3、Activity Animation(切換動畫)
Activity之間切換也是有動畫的,咱們能夠直接拿系統默認的動畫,也可使用自定義的動畫
Intent intent = new Intent(); intent.setClass(mainActivity.this,TweenAnimationActivity.class); startActivity(intent); overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out);//系統自帶的切換動畫
放在intent跳轉antivity的後面。
自帶的動畫這樣寫
//若是這個地方想用本身的,能夠調用anim文件夾下的xml文件,以下: overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
xml文件
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="300" android:fromYDelta="100%p" android:toYDelta="0" /> <alpha android:duration="300" android:fromAlpha="0.0" android:toAlpha="1.0" /> </set>
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <!-- push_up_out 上下滑入式 --> <translate android:duration="300" android:fromYDelta="0" android:toYDelta="-100%p" /> <alpha android:duration="300" android:fromAlpha="1.0" android:toAlpha="0.0" /> </set>
overridePendingTransition(arg1,arg2);
裏面的兩個參數分別是進入的activity動畫和退出的activity動畫。
4、ObjectAnimator(屬性動畫)
Animator框架是Android 4.0中新添加的一個動畫框架,和以前的Animation框架相比,Animator能夠進行更多和更精細化的動畫控制,並且比以前更簡單和更高效。在4.0源碼中隨處均可以看到Animator的使用。
Animation框架定義了透明度,旋轉,縮放和位移幾種常見的動畫,並且控制的是一個整個View動畫,實現原理是每次繪製視圖時View所在的ViewGroup中的drawChild函數獲取該View的Animation的Transformation值,而後調用canvas.concat(transformToApply.getMatrix()),經過矩陣運算完成動畫幀,若是動畫沒有完成,繼續調用invalidate()函數,啓動下次繪製來驅動動畫,動畫過程當中的幀之間間隙時間是繪製函數所消耗的時間,可能會致使動畫消耗比較多的CPU資源。
在Animator框架中使用最多的是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator進行更精細化控制,只控制一個對象的一個屬性值,多個ObjectAnimator組合到AnimatorSet造成一個動畫。並且ObjectAnimator可以自動驅動,能夠調用setFrameDelay(long frameDelay)設置動畫幀之間的間隙時間,調整幀率,減小動畫過程當中頻繁繪製界面,而在不影響動畫效果的前提下減小CPU資源消耗。
//第一個參數是屬性,即要變化的屬性,下面是變化的值,能夠放置多個數值 PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X,100); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 1f); PropertyValuesHolder pvhR = PropertyValuesHolder.ofFloat(View.ROTATION, 730); PropertyValuesHolder pvhsX = PropertyValuesHolder.ofFloat(View.SCALE_X, 1,2,1); PropertyValuesHolder pvhsY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1,2,1); PropertyValuesHolder pvhA = PropertyValuesHolder.ofFloat(View.ALPHA, 1); final ObjectAnimator animation = ObjectAnimator.ofPropertyValuesHolder(iv, pvhX, pvhY, pvhR, pvhsX, pvhsY, pvhA); animation.setDuration(2000); animation.setInterpolator(new OvershootInterpolator(0.9f)); animation.start();
主要是ObjectAnimator,其ObjectAnimator.ofPropertyValuesHolder(view,PropertyValuesHolder...)的方法是給view設置一系列的動畫,與AnimationSet相似。
詳細的用法能夠 參考文章(5)ApiDemos解析
完整代碼:
package com.cpacm.demo.testrep; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.animation.OvershootInterpolator; import android.widget.Button; import android.widget.ImageView; public class ObjectAnimatorActivity extends Activity implements View.OnClickListener{ private ImageView iv; private Button b1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_object_animator); iv = (ImageView)findViewById(R.id.imageView2); b1 = (Button)findViewById(R.id.button); b1.setOnClickListener(this); } @Override public void onClick(View v) { switch(v.getId()){ case R.id.button: //第一個參數是屬性,即要變化的屬性,下面是變化的值,能夠防止多個數值 PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X,100); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 1f); PropertyValuesHolder pvhR = PropertyValuesHolder.ofFloat(View.ROTATION, 730); PropertyValuesHolder pvhsX = PropertyValuesHolder.ofFloat(View.SCALE_X, 1,2,1); PropertyValuesHolder pvhsY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1,2,1); PropertyValuesHolder pvhA = PropertyValuesHolder.ofFloat(View.ALPHA, 1); final ObjectAnimator animation = ObjectAnimator.ofPropertyValuesHolder(iv, pvhX, pvhY, pvhR, pvhsX, pvhsY, pvhA); animation.setDuration(2000); animation.setInterpolator(new OvershootInterpolator(0.9f)); animation.start(); break; } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.object_animator, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
效果:
5、結束語
動畫在android的UI設計中老是佔着一席之地,動畫每每會給用戶帶來一種生動的感受,因此學習好動畫的設計是很重要的。這篇文章列舉的動畫種類可能不全,我也是根據本身用過的動畫作了個總結而已,若是還有其餘的動畫API歡迎你們補充。那麼你們下次再見~
參考文章:(1) Android動畫效果 第九章 http://book.51cto.com/art/201204/328247.htm
(2)詳解Android動畫之Frame Animation http://blog.csdn.net/liuhe688/article/details/6657776
(3)Android Activity之間動畫完整版詳解 http://mzh3344258.blog.51cto.com/1823534/807337
(5)ApiDemos解析:多屬性動畫 http://www.cnblogs.com/mengdd/archive/2013/09/06/3305698.html
Demo地址:https://github.com/cpacm/android_learn/tree/master/AnimationDemo
========================================
做者:cpacm