在Android 4.4(KitKat)中,谷歌添加了很多不錯的東西。現在我們來看看android.transition架構。
多年來,android不斷改進現有的動畫工具供開發者使用。在HoneyComb版本中,提供了很多不錯的API用于建立豐富、複雜的動畫。在此基礎上,KitKat的android.transition讓我們可以通過一種更直覺的方式定義動畫效果。
Scene和Transition
先從Scene和Transition概念說起。Scene定義了界面的目前狀态資訊,而Transition定義了界面之間的切換。
可以從布局檔案中載入Scene定義,示例如下:
1 | |
其中
container
在Scene中是一個包含了所有view的ViewGroup。如果是在fragment中,Scene就是傳入
onCreateView()
方法的參數。使用Transition的最簡單方式就是使用
TransitionManager
處理,示例如下:
1 | |
如果在
TransitionManager
中不明确需要指定哪個Transition,就會預設使用
AutoTransition
,這個我們會後面介紹。也可以用
inflater
載入現有的view來建立Scene,示例如下:
1 2 | |
Andorid.Transition實踐
我們來看一個更詳細的示例,首先從項目首頁下載下傳示例代碼AndroidTransitionExample。這已經是一個已完成的項目了,是以也可以用
git checkout
檢出代碼(以下是詳細解釋)。
首先建立隻包含一個Fragment的項目,這樣可以更容易記錄一些資訊。我們為
TransitionFragment
建立一個xml布局檔案,叫做fragment_transition_scene_1.xml。接着往裡面添加一個
TextView
,然後在
TextView
下面再添加一個Button,如下:
fragment_transition_scene_1.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
你一定猜得到,我們接下來還要建立另一個xml布局檔案,fragment_transition_scene_2.xml。它和上一個布局檔案基本一樣,隻是把Button移到布局底部。示例如下:
1 2 3 4 5 6 7 8 9 | |
這是兩個布局的螢幕截圖:
為了看Transition的效果,我們從第二個布局檔案中建立Scene。點選goButton的時候展示Transition的效果。我們先修改一下
TransitionFragment.onCreateView()
方法的代碼,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
這是點選goButton的效果:
為什麼會産生這樣的效果呢?因為如果view有相同的ID,就會被當做是同一個view,然後也會被改變(通過改變bounds),也就是說,在Scene切換時,view的位置和大小也會改變,需要注意的是兩個布局檔案的
RelativeLayout
也要有相同的ID。
使用GIT實戰
如果你對整個例子代碼感興趣的話,也可以利用GIT檢出代碼。從AndroidTransitionExample複制一份即可,你可以用GUI git用戶端列出項目的曆史版本,也可以定位到某個具體的送出點檢出。
當然,你也可以使用指令行。使用
cd
指令切換到項目檔案夾,然後執行以下指令:
1 | |
此時,你會得到項目的送出清單,像這樣:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
以上貼出的對應于simple transition這個送出點,執行以下代碼可以把項目設定成這個狀态:
1 | |
執行
git checkout
,你可以跳到任意一個送出點上,下面的插入文字會給出訓示操作。
修改布局檔案
我們來修改一下第二個布局檔案,首先把
RelativeLayout
換成
LinearLayout
,然後我們來介紹一個在第一個布局檔案中沒有出現的view,最後我們重新排布一下這些view,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
我們目前處于“1e7c5be modified layout for scene 2”送出點,在指令行執行
git checkout 1e7c5be
就可以切換上去。可以看到,Transition仍然起作用,在第一個Scene裡面,不存在的view竟然出現在螢幕上,然後随着Button和TextView的移動而逐漸消失。
我們詳細看看AutoTransition,事實證明,它隻是
TransitionSet
的子類,隻是它給自己定義了一個執行序列,分别是fading out、changing bounds、fading in。
我們注意到,在第二個Transition中,AutoTransition會改變bounds,目前我們隻看到了Button和TextView改變了位置,如果我們改變view的大小會出現什麼情況呢?在Button中添加layout_weight屬性來看看效果:
1 2 3 4 5 6 | |
現在Button在轉變的過程中既改變了位置也改變了大小。
現在切換到“added layout_weight to button”這個點,指令:
git checkout 092ebe0
。現在再做一些變化效果,在Scene中把Button轉變成
ImageView
:
1 2 3 4 5 6 7 | |
此時切換到“example of transitioning from Button to ImageView”這個點,指令:
git checkout 6b4629c
。看看從Button變成
ImageView
的效果:
仔細看你會發現,第一個Button首先被一張切割過的圖檔替換了,然後逐漸移動到最終的位置,逐漸改變大小。
如果我們改變所有views的嵌套結構,比如在Button外面套一層
LinearLayout
,那麼Bounds就不會改變了。transition manager要求在Scene的布局檔案中,同一層級的view要有和之前相同的ID:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
此時切換到“example of change bounds not working when changing hierarchy”這個點,指令:
git checkout 2b000b3
。
如果我們在第一個Scene中繼續用
LinearLayout
包含Button,那麼還是不行。想讓它起作用的話,可以給
LinearLayout
一個相同的ID。這會得到兩種不同的效果。
切換到“restore transition by adding LinearLayout with id”,指令:
git checkout 34e0f8f
下一篇我們我們繼續研究怎麼控制Transition,以及如何從xml檔案中載入Transition。
原文位址 http://blog.jobbole.com/62601/