緊接着上一篇介紹了Scene和Transition的基本用法後,這篇開始介紹如何運用這些到轉場動畫中。從A頁面到B頁面,再從B頁面返回到A頁面,這就是一個完整的轉場過程。而轉場動畫就是負責來優雅地協調處理好這個過程的。android
Content Transition就是最多見的轉場動畫了。爲了方便你們理解,咱們先來上個圖。bash
Slide slide=new Slide();
slide.setDuration(3000);
slide.setSlideEdge(Gravity.BOTTOM);
getWindow().setExitTransition(slide);
Explode explode = new Explode();
explode.setDuration(3000);
explode.setMode(Visibility.MODE_IN);
getWindow().setReenterTransition(explode);
複製代碼
Slide slideEnter=new Slide();
slideEnter.setDuration(1500);
slideEnter.setSlideEdge(Gravity.RIGHT);
getWindow().setEnterTransition(slideEnter);
Slide slide=new Slide();
slide.setDuration(1500);
slide.setSlideEdge(Gravity.RIGHT);
getWindow().setReturnTransition(slide);
複製代碼
而後在A頁面調用方法跳到B頁面:ide
Intent intent = new Intent(this, BActivity.class);
ActivityOptionsCompat activityOptionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this);
startActivity(intent, activityOptionsCompat.toBundle());
複製代碼
能夠看到一共能夠設置四個Transition:佈局
(1)setExitTransition() - 當A 跳轉到 B時,A中的View退出場景的效果(默認Null)post
(2)setEnterTransition() - 當A 跳轉到 B時,B中的View進入場景的效果(默認Fade)動畫
(3)setReturnTransition() - 當B 返回 A時,B中的View退出場景的效果(默認同EnterTransition)ui
(4)setReenterTransition() - 當B 返回 A時,A中的View進入場景的效果(默認同ExitTransition)this
以上這個過程一樣能夠看作是Transition做用在Scene上的一系列效果,只不過這裏的Scene從上一篇中的單一佈局換成了Window。不過細心的同窗可能發現了,明明我爲四個過程都設置動畫效果,可爲何ExitTransition沒有生效呢?接下來咱們爲每一個Transition加入監聽,看看動畫的執行流程。下面是其中一個的代碼,其餘三個都同樣:spa
Explode explode = new Explode();
explode.setDuration(3000);
explode.setMode(Visibility.MODE_IN);
explode.addListener(new Transition.TransitionListener(){
@Override
public void onTransitionStart(Transition transition) {
Log.d("Transitions--","ReenterTransitionStart");
}
@Override
public void onTransitionEnd(Transition transition) {
Log.d("Transitions--","ReenterTransitionEnd");
}
@Override
public void onTransitionCancel(Transition transition) {
}
@Override
public void onTransitionPause(Transition transition) {
}
@Override
public void onTransitionResume(Transition transition) {
}
});
getWindow().setReenterTransition(explode);
複製代碼
再次執行程序,日誌信息以下: 3d
getWindow().setAllowEnterTransitionOverlap(false);
getWindow().setWindowAllowReturnTransitionOverlap(false);
複製代碼
或者在主題文件全局設置這個屬性,這樣無疑更好,即減小了代碼又保證了應用視覺效果的統一:
<item name="android:windowAllowEnterTransitionOverlap">false</item>
<item name="android:windowAllowReturnTransitionOverlap">false</item>
複製代碼
修改後效果以下:
保持上面的打印信息不變,咱們增長兩個Activity的生命週期日誌信息,串行結果以下:
onBackPressed()
纔會有ReturnExitTransition。看源碼就很明顯了:public void onBackPressed() {
if (mActionBar != null && mActionBar.collapseActionView()) {
return;
}
if (!mFragments.getFragmentManager().popBackStackImmediate()) {
finishAfterTransition();
}
}
複製代碼
最後簡單分析下轉場動畫的大體流程(以slide爲例),看過上一篇文章的同窗應該很好理解:
1.從DecoerView開始,依次遍歷得到當前Window上的視圖樹裏的全部View
2.執行captureStartValues(TransitionValues transitionValues),捕獲View開始狀態的一些屬性(visibility,Parent,LocationOnScree)
3.設置全部的VIew爲INVISIBLE。
4.執行captureEndValues(TransitionValues transitionValues),捕獲View結束狀態的一些屬性(visibility,Parent,LocationOnScree)
5.比較屬性的不一樣,建立屬性動畫。下一個過程就是返回屬性動畫並執行了。
複製代碼
這是ExitTransiton的流程,其餘三個也差很少。下一篇將會講帶共享元素的轉場動畫,也是material design中頗有特點的動畫了。