本文由湫水投稿。
湫水的博客地址:
http://blog.csdn.net/wl9739
Android 中的動畫有很多,除了在一個界面上使用幀動畫、屬性動畫將一個或多個 View 進行動畫處理以外,還可以用於兩個界面之間過渡、跳轉。在 Android 5.0 之前,我們已經有了 overridePendingTransition() 方法來實現一些轉場效果。然而,在 Android 5.0 以後,轉場效果更加炫酷。 比如下面的動畫:
本篇文章,主要就是解說如何實現上述的效果。主要內容包括:
在 res/ 目錄下創建 transition 文件夾,在該文件夾下定義界面轉場動畫和共享元素的動畫。
在 res/value/style 文件中為每個 Activity 指定轉場動畫的 style ,並在 AndroidManifest.xml 文件中為每個 Activity 設置對應的 android:theme。
在 Activity 調用 startActivity() 切換動畫前,使用 ActivityOptionsCompat 來創建轉場動畫時的共享對象。
下面就來對這三步進行詳細講解。
在 res/ 目錄下創建了 transition 資源文件夾後,就可以在該文件夾下對每一種動畫進行定義。
一般來說,對 Activity 定義一個過渡動畫可以寫成下面的形式:
其中, 是動畫效果的名稱,Android 5.0(API 級別 21)支持這些進入與退出轉換:
而每一種動畫效果,都有額外的屬性。比如滑動 slide,可以使用 android:slideEdge="top" 設置滑動的方向;淡入淡出(fade)可以使用 android:fadingMode="fade_in" 設置具體是淡入(fade_in)還是淡出(fade_out)等。
標籤裡面定義需要轉場(或者不需要轉場)的目標 id ,這個 id 可以使系統自帶的,也可以是我們自己視圖中的 view 的 id,每一個 id 需要單獨在 標籤中定義,android:targetId 表示目標ID需要進行過渡轉換的 view,而 android:excludeId 表示我們不需要該 ID 的 view 進行過渡轉場。上面的那段代碼的意思是說,除了狀態欄和導航欄以外所有的 view,都執行 explode 動畫。
如果我們想要在同一個過渡狀態中實現兩種或多種動畫效果怎麼辦?
也簡單,將根標籤替換為 ,然後定義每一種動畫效果,最後記得在根標籤中使用 android:transitionOrdering 註明這幾種動畫的演示順序,sequential 表示順序執行,而 together 表示同時執行。比如像下面的代碼:
這段代碼的意思就很簡單了,該 xml 定義了兩個過渡動畫,並且同時執行。第一個動畫是針對 id 為 cardView 的 view 進行滑動,第二個動畫將除了狀態欄、導航欄和 cardview 以外的 view,進行淡入淡出。
為每個 Activity 定義轉場樣式這裡的每一種動畫,指的是在進行界面跳轉過渡時,兩個界面的狀態。比如對於 Activity A 和 Activity B 這兩個界面,可能的狀態如下:
一般來說,所有的 Activity 過渡動畫都可以定義成如下的形式:
當然,你可以不用寫全,比如在我的 Demo 中一個界面的轉場動畫文件如下:
轉場動畫是在兩個界面的跳轉返回時發生的,所以,當使用 intent 跳轉界面時,需要調用 ActivityOptionsCompat來指定動畫的運行。
一般來說,調用 ActivityOptionsCompat 的模板代碼如下:
ActivityOptionsCompat 是在support v4 包裡面的,其實它是 ActivityOptions 的一個兼容(ActivityOptions是API 16引入的)。
然後,我們需要在第二個 Activity 中,將轉場的圖片獲取並顯示到界面中就可以了。
多個共享元素的過渡實現
有時候我們需要讓多個元素產生動畫效果,可以使用 Pair 來實現:
實現的思路也比較簡單,大概的步驟如下:
那麼我們開始一步步實現上面的步驟。
獲取共享元素位置信息在第一個界面中,我們需要獲取到共享元素的位置信息,並將其傳遞給下一個界面。於是乎,我們可以在第一個界面元素點擊事件中,這麼寫:
其中,getGlobalVisibleRect() 方法的含義是,獲取 可見的狀態欄高度+可見的標題欄高度+Rect左上角到標題欄底部的距離,如果標題欄被隱藏了,那麼可見標題欄高度為0。
接下來,就在在第二個界面接收位置信息並將該圖片展示出來了。
在第二個界面中,我們需要做如下的操作:
獲取上共享元素信息。
計算共享元素縮放比例和位移距離。
調用動畫,完成模擬轉場效果。
我將上面三個步驟的代碼如下,你也可以下載我完整的 Demo(https://github.com/wl9739/UITransitionDemo) 來查看。
在12行,通過設置 Margin 的形式來確定圖片的位置,需要注意的是,由於狀態欄是在父控制項 FramLayout 之外的,因此我們要將 Rect.top 的值減去狀態欄的高度,這樣才是相對於屏幕的絕對位置。然後,getBundleInfo() 方法的代碼如下:
最後我們需要使用動畫來模擬轉場效果,代碼如下:
很簡單,至此,入場動畫效果基本模擬完畢。
而退場動畫就更簡單了,直接上代碼:
當然,這只是簡單的模擬,如果想要和 Android 5.0+ 的轉場效果相同,還需要做很多的動畫處理。
本篇文章的 Demo 地址:
https://github.com/wl9739/UITransitionDemo
推薦閱讀:定義定製動畫
https://developer.android.com/training/material/animations.html?hl=zh-cn
如果你有好的文章想和大家分享,歡迎投稿,直接向我投遞文章連結即可。
歡迎長按下圖->識別圖中二維碼或者掃一掃關注我的公眾號: