Android轉場動畫一說
所謂轉場動畫,通俗的講就是一個Activity跳轉到另一個Activity是的動畫。
Activity的轉場動畫很早就有了,5.0之前用的是overridePendingTransition()這個方法。在5.0之後,Google使用Material Design設計風格,進而有了的新的轉場轉場動畫的誕生,效果還是挺炫酷的,下面我們先看下效果。
5.0之前的效果
使用方法:
在startActivity後加入以下程式碼
startActivity(Intent(this@BeforeActivity,BeforeTwoActivity::class.java)
//Fade(淡入淡出)
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
//Slide(左右交錯)
//overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right)
複製程式碼
然後在finish後加入以下程式碼
finish()
//Fade(淡入淡出)
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
//Slide(左右交錯)
//overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right)
複製程式碼
其實這裡主要是靠overridePendingTransition(int enterAnim, int exitAnim)來載入動畫,顧名思義第一個引數是進場動畫,第二個是出場動畫。 這幾個效果是可以互動使用,比如進場用Fade效果,出場用SLide效果。也可以使用自定義的效果,這裡不細說。當然5.0後了類似共享元素這類的效果那就另當別論了
5.0之後的效果(過度效果和共享元素)
說到這裡不得不說Google在5.0MD設計中給我提供全新的過度動畫ActivityOptions,以及相容包ActivityOptionsCompat.下面來說一說它提供幾種過度效果的方法
第一種
ActivityOptionsCompat makeCustomAnimation(Context context,int enterResId, int exitResId)。
這個方法其實和上面的overridePendingTransition()方法使用其實差不多,第二個引數是進場動畫,第三個是出場動畫。(效果參考overridePendingTransition()) 使用如下:
startActivity的時候:
ActivityCompat.startActivity(Intent(this@BeforeActivity,BeforeTwoActivity::class.java),
ActivityOptionsCompat.makeCustomAnimation(this@BeforeActivity,
android.R.anim.fade_in, android.R.anim.fade_out).toBundle())
複製程式碼
####finish的時候:
ActivityCompat.finishAfterTransition(this)
複製程式碼
但是這個方法呼叫後,會發現並沒有什麼軟用,沒有退出的動畫。打斷點除錯後發現:
public boolean startExitBackTransition(final Activity activity) {
if (mEnteringNames == null || mCalledExitCoordinator != null) {
return false;
} else {
...
}
}
複製程式碼
這個mEnteringNames一直是null,然後這個變數跟共享元素有關:
/**
* The shared elements that the calling Activity has said that they transferred to this
* Activity.
* 呼叫Activity的共享元素表示已轉移到此Activity(請不要介意這個機翻,湊和看)
*/
private ArrayList<String> mEnteringNames;
複製程式碼
因為這個兩個頁面之間涉及到共享元素,這裡沒有使用到,所以要想這個有出場動畫,還是呼叫overridePendingTransition()來顯示(有更好的方法請告知,萬分感謝)
第二種
ActivityOptionsCompat makeScaleUpAnimation(View source,int startX, int startY, int startWidth, int startHeight)
這個效果展示的某個小的區域放大至全屏顯示,效果如下:
這個方法第一個引數是目標view(也就是想要放大的view),第二、三個引數是起始座標,第四,五個引數是過度效果開始的寬高度 使用如下:
startActivity的時候:
val options = ActivityOptionsCompat.makeScaleUpAnimation(view,view.width/2,view.height/2,
0, 0)
ActivityCompat.startActivity(this@AfterActivity,Intent(this@AfterActivity,AfterTwoActivity::class.java),options.toBundle())
複製程式碼
finish的時候(這個沒什麼回退效果,暫時沒找到解決方法,有更好的方法請告知,萬分感謝):
ActivityCompat.finishAfterTransition(this)
複製程式碼
第二種
ActivityOptionsCompat makeScaleUpAnimation(View source,int startX, int startY, int startWidth, int startHeight)
這個效果展示的某個小的區域放大至全屏顯示,效果如下:
這個方法第一個引數是目標view(也就是想要放大的view),第二、三個引數是起始座標,第四,五個引數是過度效果開始的寬高度 使用如下:
startActivity的時候:
val options = ActivityOptionsCompat.makeScaleUpAnimation(view,view.width/2,view.height/2,
0, 0)
ActivityCompat.startActivity(this@AfterActivity,Intent(this@AfterActivity,AfterTwoActivity::class.java),options.toBundle())
複製程式碼
finish的時候(這個沒什麼回退效果,暫時沒找到解決方法,有更好的方法請告知,萬分感謝):
ActivityCompat.finishAfterTransition(this)
複製程式碼
第三種
ActivityOptionsCompat makeThumbnailScaleUpAnimation(View source,Bitmap thumbnail, int startX, int startY)
這個效果展示的一塊的Bitmpat進行拉伸的動畫,效果如下:
這個方法第一個引數是目標view(也就是想要放大的view),第二引數是需要放大的圖片,第四,五個引數是起始座標 使用如下:
startActivity的時候:
var bitmap = BitmapFactory.decodeResource(resources,effect.uri)
val options = ActivityOptionsCompat.makeThumbnailScaleUpAnimation(view, bitmap,
view.width/2, view.height/2)
ActivityCompat.startActivity(this@AfterActivity,Intent(this@AfterActivity,AfterTwoActivity::class.java),options.toBundle())
複製程式碼
finish的時候(這個沒什麼回退效果,暫時沒找到解決方法,有更好的方法請告知,萬分感謝):
ActivityCompat.finishAfterTransition(this)
複製程式碼
第四種
ActivityOptionsCompat makeClipRevealAnimation(View source,int startX, int startY, int width, int height)
這個效果展示的從一個點以圓形漸變到滿屏,效果如下:
這個方法第一個引數是目標view(也就是想要放大的view),第二、三個引數是起始座標,第四,五個引數是過度效果開始的寬高度 使用如下:
startActivity的時候:
val options = ActivityOptionsCompat.makeClipRevealAnimation(view,view.width/2,
view.height/2,0, 0)
ActivityCompat.startActivity(this@AfterActivity,Intent(this@AfterActivity,AfterTwoActivity::class.java),options.toBundle())
複製程式碼
finish的時候(這個沒什麼回退效果,暫時沒找到解決方法,有更好的方法請告知,萬分感謝):
ActivityCompat.finishAfterTransition(this)
複製程式碼
第五種
####ActivityOptions CompatmakeSceneTransitionAnimation(Activity activity,Pair<View, String>... sharedElements)
這個展示的多種效果,效果如下:
這個方法第一個引數是目標view(也就是想要放大的view),第二個引數是共享元素需要的(這裡的效果不涉及) 使用如下:
startActivity的時候:
startActivity(Intent(this@AfterActivity, AfterTwoActivity::class.java),
ActivityOptionsCompat.makeSceneTransitionAnimation(this@AfterActivity).toBundle())
複製程式碼
然後在跳轉後的頁面設定效果(這裡是AfterTwoActivity):
//Explode
window.enterTransition = Explode()
window.exitTransition = Explode()
//Slide
window.enterTransition = Slide()
window.exitTransition = Slide()
//Fade
window.enterTransition = Fade()
window.exitTransition = Fade()
複製程式碼
共享元素
所謂的共享元素指的是Activity A中一個View和Activity B中的一個View做一個平滑過渡的效果。
效果展示(類似微信朋友圈的圖片放大效果) :
來看一下如何來讓兩個頁面之間的View做一個過渡:
-
1.在A和B的佈局中為需要進行過渡效果的View設定兩個相同的 android:transitionName = “標識名稱”
-
2.1 在startActivity的時候(適用單個view過渡):
//第二引數傳入過渡的view,第三個引數傳入 android:transitionName 標識名稱 startActivity(Intent(this@ShareElementActivity, ShareElementTwoActivity::class.java), ActivityOptions.makeSceneTransitionAnimation(this@ShareElementActivity,view,"shareImg").toBundle()) 複製程式碼
-
2.2 在startActivity的時候(適用多個個view過渡):
//其實就是把過個需要過渡的View集合起來 var one = android.support.v4.util.Pair<View, String>(img5, "shareImg5") var two = android.support.v4.util.Pair<View, String>(img6, "shareImg6") var pairs = arrayOf(one,two) val transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(this, *pairs) startActivity(Intent(this@ShareElementActivity, ShareElementThreeActivity::class.java), transitionActivityOptions.toBundle()) 複製程式碼