在前一篇文章中,我們初步瞭解android.transition框架並開始著手AndroidTransitionExample專案。今天,我們將繼續進一步探索如何使用這些類,以及如何從xml檔案中載入他們。
為了使用示例工程,我們可以參照前一篇文章中“使用GIT實戰”章節。下面是文件給出的一些額外提示。
控制過度效果
讓我們來看看如何控制過度效果。首先,我們要進行一下重構。提取goToScene
方法,而不是直接呼叫TransitionManager.go()
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
; html-script: false ]... goButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //TransitionManager.go(scene); //移除 goToScene(scene); } }); ... private void goToScene(Scene scene) { ChangeBounds changeBounds = new ChangeBounds(); Fade fadeOut = new Fade(Fade.OUT); Fade fadeIn = new Fade(Fade.IN); TransitionSet transition = new TransitionSet(); transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL); transition .addTransition(fadeOut) .addTransition(changeBounds) .addTransition(fadeIn); TransitionManager.go(scene, transition); } |
轉到“extract method goToScene”:
1 |
; html-script: false ]git checkout 6ea37f7 |
效果是一樣的。事實上,如果用AutoTransition效果
也一樣。但是,這樣我們有更多控制,因為這樣能把transition集合裡的元件繫結到我們的連結上。例如,我們可以改變動畫持續的時間:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
; html-script: false ]private void goToScene(Scene scene) { ChangeBounds changeBounds = new ChangeBounds(); changeBounds.setDuration(1000); Fade fadeOut = new Fade(Fade.OUT); fadeOut.setDuration(1000); Fade fadeIn = new Fade(Fade.IN); fadeIn.setDuration(1000); TransitionSet transition = new TransitionSet(); transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL); transition .addTransition(fadeOut) .addTransition(changeBounds) .addTransition(fadeIn); TransitionManager.go(scene, transition); } |
轉到“slow motion transitions”:
1 |
; html-script: false ]git checkout fbcc465 |
因為某些原因,在開發者選項裡的動畫控制看起來並不能影響動畫過度效果。
上面的程式碼讓我們可以慢速檢視動畫。我們能控制的不僅僅只有過度的時間而已,還可以嘗試新增一個內插程式。經典動畫的原則之一說到:角色不能簡簡單單的就開始移動。他們先要展現出要移動的動作,然後移動,最後在停止之前完成動作(Overshoot)。使用內建的AnticipateOvershootInterpolator
能得到想要的效果。注意:我們放慢了邊緣動畫的變動效果,所以很容易看到效果。
1 2 3 4 |
; html-script: false ]ChangeBounds changeBounds = new ChangeBounds(); changeBounds.setInterpolator(new AnticipateOvershootInterpolator()); changeBounds.setDuration(2000); Fade fadeOut = new Fade(Fade.OUT); |
轉到“use AnticipateOvershootInterpolator”:
1 |
; html-script: false ]git checkout 1de57f0 |
在過度到第二場景後,如果你試著按下“執行轉換按鈕”會發現並沒有什麼發生。這是因為,唯一繫結OnClickListener
(點選監聽)的按鈕在第一個layout裡。要使第二個場景的按鈕正常工作,我們需要另外載入不同場景的介面。
1 2 3 4 5 6 7 8 |
; html-script: false ]View rootView = inflater.inflate(R.layout.fragment_transition_scene_1, container, false); /*final Scene scene = Scene.getSceneForLayout(container, R.layout.fragment_transition_scene_2, getActivity());*/ //移除 View secondView = inflater.inflate(R.layout.fragment_transition_scene_2, container, false); final Scene scene = new Scene(container, (ViewGroup)secondView); Button goButton = (Button)rootView.findViewById(R.id.goButton); |
現在,我們有了第二檢視,可以開啟第二個按鈕:
1 2 3 4 5 6 7 8 |
; html-script: false ]final Scene originalScene = new Scene(container, (ViewGroup)rootView); Button goBackButton = (Button)secondView.findViewById(R.id.goButton); goBackButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { goToScene(originalScene); } }); |
最終效果如下圖所示:
轉到“add the return transition”:
1 |
; html-script: false ]git checkout 9871bfa |
用XML實現過度
到現在為止,我們看了在程式碼中使用轉換框架。當然,也可以通過XML實現。KitK介紹了全新的資原始檔夾過度方法,這樣的資料夾儲存了定義轉換,甚至是場景對映的XML檔案。
例如,使用XML來定義自定義的轉換會這樣寫(使用slow_auto_transition.xml):
1 2 3 4 5 6 7 8 9 10 11 12 13 |
; html-script: false ]<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:transitionOrdering="sequential"> <fade android:fadingMode="fade_out" android:duration="1000"/> <changeBounds android:duration="2000" android:interpolator="@android:interpolator/anticipate_overshoot"/> <fade android:fadingMode="fade_in" android:duration="1000"/> </transitionSet> |
使用XML檔案能簡化我們goToScene方法:
1 2 3 4 5 6 |
; html-script: false ]private void goToScene(Scene scene) { TransitionInflater inflater = TransitionInflater.from(getActivity()); Transition transition = inflater.inflateTransition(R.transition.slow_auto_transition); TransitionManager.go(scene, transition); } |
現在執行這個專案,結果和之前的是完全相同的。
轉到“inflate the transition from the XML file”:
1 |
; html-script: false ]git checkout c2a25d4 |
使用XML進行過度管理
正如上文提及到的那樣,可以通過XML檔案增加一個完整的transition管理例項。它定義了從一個場景到另一個場景的轉換。我們最後對工作做一點改變。下面是transition_manager.xml檔案:
1 2 3 4 5 6 7 8 9 10 |
; html-script: false ]<transitionManager xmlns:android="http://schemas.android.com/apk/res/android"> <transition android:fromScene="@layout/fragment_transition_scene_1" android:toScene="@layout/fragment_transition_scene_2" android:transition="@transition/slow_auto_transition"/> <transition android:fromScene="@layout/fragment_transition_scene_1" android:toScene="@layout/fragment_transition_scene_2" android:transition="@transition/slow_auto_transition"/> |
同樣我們也修改一下layout,以便不用再在程式碼中修改button的連結方式:在第一層layout中為id為goButton的按鈕新增android:onClick="goToScene2"
函式。同樣,在第二層layout中新增android:onClick="goToScene1"
。
1 2 3 4 5 6 |
; html-script: false ] <Button android:id="@+id/goButton" android:text="@string/button_go" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="goToScene2"/> |
我們會把大部分的程式碼放進TransistionActivity
中,而TransitionFragment
只用來載入檢視:
1 2 3 4 5 6 |
; html-script: false ]public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate( R.layout.fragment_transition_scene_1, container, false); return rootView; } |
在TransitionActivity
中新增例項變數:
1 2 3 |
; html-script: false ]private TransitionManager mTransitionManager; private Scene mScene1; private Scene mScene2; |
在TransitionActivity
的onCreate
函式結束的地方增加下面的程式碼:
1 2 3 4 5 6 7 8 |
; html-script: false ]ViewGroup container = (ViewGroup)findViewById(R.id.container); TransitionInflater transitionInflater = TransitionInflater.from(this); mTransitionManager = transitionInflater.inflateTransitionManager( R.transition.transition_manager, container); mScene1 = Scene.getSceneForLayout(container, R.layout.fragment_transition_scene_1, this); mScene2 = Scene.getSceneForLayout(container, R.layout.fragment_transition_scene_2, this); |
結束的時候,把下面兩個函式加到TransitionActivity
類:
1 2 3 4 5 6 7 |
; html-script: false ]public void goToScene1(View view) { mTransitionManager.transitionTo(mScene1); } public void goToScene2(View view) { mTransitionManager.transitionTo(mScene2); } |
最後可以得到相同的效果。
轉到“load the transition manager from the XML file”:
1 2 3 |
; html-script: false ]git checkout cc40873 或者 git checkout master |
盡情享受Transition功能吧!