Android Activity 切換動畫及5.0以后的轉(zhuǎn)場動畫

學(xué)習(xí)收集,非原創(chuàng)

一、 簡介

在Android開發(fā)過程中,經(jīng)常會碰到Activity之間的切換效果的問題,下面介紹一下如何實現(xiàn)左右滑動的切換效果,首先了解一下Activity切換的實現(xiàn),Android已經(jīng)內(nèi)置了幾種動畫效果,可以見 android.R.anim 類。一般情況下我們需要自己定義屏幕切換的效果。首先我們先了解Activity的位置定義,如下圖:


圖圖圖

從上圖可以看出,以手機(jī)屏幕下面邊未X軸,屏幕左邊為Y軸,

  • 當(dāng)Activity在X軸值為-100%p時,剛好在屏幕的左邊(位置1),
  • 當(dāng)X軸值為0%p時,剛好再屏幕內(nèi)(位置2),
  • 當(dāng)X=100%p時剛好在屏幕右邊(位置3)。

清楚了位置后,我們就可以實現(xiàn)左右滑動的切換效果,首先讓要退出的Activity從位置2移動到位置1,同時讓進(jìn)入的Activity從位置3移動位置2,這樣就能實現(xiàn)從左右切換效果。
實現(xiàn)過程如下,首先定義2個動畫,在 res目錄創(chuàng)建anim目錄, 然后在目錄創(chuàng)建動畫的xml文件:
out_to_left.xml (從左邊退出動畫)
in_from_right.xml(從右邊進(jìn)入動畫)

out_to_left.xml (從 位置2 移動到 位置1)

<?xml version="1.0" encoding="utf-8"?>
  <set 
   xmlns:android="http://schemas.android.com/apk/res/android" 
  android:interpolator="@android:anim/accelerate_interpolator"> 
  <translate android:fromXDelta="0%p" 
   android:toXDelta="-100%p" 
   android:duration="500" />
 </set>
    in_from_right.xml (從 位置3 移動到 位置2)

    <?xml version="1.0" encoding="utf-8"?>
    <set 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:interpolator="@android:anim/accelerate_interpolator">
     <translate 
      android:fromXDelta="100%p" 
      android:toXDelta="0%p" 
      android:duration="500" />
    </set>

二 、使用windowAnimation和ActivityAnimation設(shè)置Android轉(zhuǎn)場動畫

1. windowAnimation和ActivityAnimation的區(qū)別:

顯而易見,window與Activity本身從名字上就知道不同,但對于項目開發(fā)中 windowAnimation和ActivityAnimation的區(qū)別必須心領(lǐng)神會。
區(qū)別主要如下:

    1. windowAnimation包含: windowEnterAnimationwindowExitAnimation
      ActivityAnimation包含: android:activityOpenEnterAnimationandroid:activityOpenExitAnimationandroid:activityCloseEnterAnimationandroid:activityCloseExitAnimation
    1. 在項目中WindowAnimation的控制權(quán)大于Activity的控制權(quán),即在Activity轉(zhuǎn)場過程中,如果同時設(shè)置了WindowAnimation和ActivityAnimation,那么 可能(因為這種情況非常多) 只會執(zhí)行WindowAnimation
    1. 對于WindowAnimation的定義很簡單,在style.xml文件中只需要繼承Animation Style即可
2. Android使用Theme自定義Activity進(jìn)入退出動畫

在AndroidManifest里面,對于application和activity標(biāo)簽可以定義theme屬性。如果對Application定義了某一個屬性,那么會對所有的activity產(chǎn)生影響,當(dāng)然你可以在activity中覆蓋它。

在AndroidManifestl中
對所有的activity產(chǎn)生影響
<application  android:theme="@style/AppTheme">
在activity中覆蓋它
<activity
   android:name=".ui.video.VideoDetailActivity"
   android:label="@string/title_activity_video_detail"
   android:theme="@style/AppTheme"></activity>
在values/styles.xml中
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <item name="android:windowAnimationStyle">@style/myActivityOutEnterAnima</item>
    </style>

<style name="myActivityOutEnterAnima" parent="@android:style/Animation.Activity">
        <!-- 定義activity的進(jìn)出場動畫 -->
        <item name="android:activityOpenEnterAnimation">@anim/enter_from_right</item>
        <item name="android:activityOpenExitAnimation">@anim/out_to_left</item>
        <item name="android:activityCloseEnterAnimation">@anim/enter_from_left</item>
        <item name="android:activityCloseExitAnimation">@anim/out_to_right</item>
    </style>

在values/anim.xml中
enter_from_left.xml
enter_from_right.xml
out_to_left.xml
out_to_right.xml

android:activityOpenEnterAnimation:指的是進(jìn)入B時, B的動畫。
android:activityOpenExitAnimation:指的是進(jìn)入B時,A的動畫,與B的動畫是一起顯示的。
android:activityCloseEnterAnimation:通過B跳轉(zhuǎn)到C后,后退到B時,B的進(jìn)入動畫
android:activityCloseExitAnimation:通過B跳轉(zhuǎn)到C后,后退到B時,C的退出動畫'

這樣就可以了,至于anim中的動畫,就自己定義啦,這個和普通的animation是一樣的,如果不知道的話,請參見http://developer.android.com/guide/topics/graphics/view-animation.html
這種方式除了可以定義activity的animation之外,還有task,window出現(xiàn)和結(jié)束時候的動畫,具體請參見
http://developer.android.com/reference/android/R.styleable.html#WindowAnimation

從上述2中動畫的定義上來看,顯然ActivityAnimation更為復(fù)雜,但這種復(fù)雜帶來的轉(zhuǎn)場效果非常好,可以同時控制2個Activity的動畫,而不像WindowAnimation只能控制下一個Activity的窗體動畫。

三、 窗體動畫也可以使 Activity. overridePendingTransition來設(shè)置

從Android2.0開始在Activity增加了一個方法:
public void overridePendingTransition (int enterAnim, int exitAnim) 其中:

  • enterAnim 定義Activity進(jìn)入屏幕時的動畫
  • exitAnim 定義Activity退出屏幕時的動畫

注:overridePendingTransition 方法必須在startActivity()或者 finish()方法的后面。當(dāng)時沒法定義退出的動畫

四、 5.0以后的轉(zhuǎn)場動畫

1. 概述

毫無疑問,動畫效果能提高用戶體驗。我們平時使用最多的動畫基本上是屬性動畫和補間動畫了,屬性動畫很強,基本能定制我們想要的動畫,但是你是否知道,API 21(5.0)后系統(tǒng)內(nèi)置了Activity之間的切換動畫,而且非常酷炫,今天我跟大家一起分享一下。

我們知道,在兩個Activity之間切換,我們一般會寫出類似下面的代碼:

在API 21以后,我們可以使用內(nèi)置的Activity切換動畫啦。

但是這樣也就意味著只能兼容5.0之后的系統(tǒng),我們先看一個效果圖來壓壓驚:

先看看第一個Activity,退出時用的是Explode效果,第二個Activity進(jìn)入時用的是Slide效果。

這些效果無需我們自己去實現(xiàn),都是內(nèi)置的效果,我們所編寫的代碼幾乎為零,接下來我們一一看看內(nèi)置了哪些效果。

2.使用內(nèi)置Activity切換動畫的步驟

Activity之間的切換期間,對于某個Activity來說,無非就是“進(jìn)入”和“退出”兩種情景下的動畫。
而“進(jìn)入”分為“第一次進(jìn)入Activity”和“返回當(dāng)前Activity”這兩種情況。

另外系統(tǒng)還提供了一種動畫,即共享元素,這是讓兩個Activity中的View有個過渡切換的效果。
執(zhí)行動畫的狀態(tài)如下所示:

  • enter:用于決定第一次打開當(dāng)前Activity時的動畫

  • exit : 用于決定退出當(dāng)前Activity時的動畫

  • reenter: 用于決定如果當(dāng)前Activity已經(jīng)打開過,并且再次打開該Activity時的動畫

  • shared elements:用于決定在兩個Activity之間切換時,指定兩個Activity中對應(yīng)的View的過渡效果

那么應(yīng)該怎么去使用Activity切換動畫呢?

我們看看使用步驟:
  • ** 首先在setContentView()之前執(zhí)行,用于告訴Window頁面切換需要使用動畫接下來就是加載切換動畫**
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
  • 接下來就是加載切換動畫
    其中R.transition.explode就是要執(zhí)行的動畫,是在res/transition目錄下的xml文件,我們使用的是系統(tǒng)內(nèi)置的Explode效果動畫,關(guān)于怎么去寫explode.xml,我們接下來小節(jié)去講解。
  • 告訴Window,當(dāng)前的Activity在什么情況下使用上面的動畫
    上面我們創(chuàng)建好了切換動畫,接下來就是要告訴當(dāng)前窗口,在什么情況下去使用動畫效果啦,你可以根據(jù)你的需求在不同的切換情景中選擇不同的效果:

當(dāng)然了,你也可以不使用代碼的方式,直接在你使用的主題

  • 調(diào)用startActivity
    跟我們之前使用的startActivity(Intent intent);不同,這里多了一個參數(shù)Bundle,我們是先通過makeSceneTransitionAnimation函數(shù)創(chuàng)建一個ActivityOptions對象,再將其轉(zhuǎn)為Bundle對象:

整體使用步驟就是以上這些,是不是很簡單?接下來我們?nèi)W(xué)習(xí)如何使用內(nèi)置動畫~

3.使用內(nèi)置動畫

3.1 Explode效果

Explode即爆炸效果,使用Explode效果很簡單,在res/transition目錄下新建一個xml文件(如explode.xml),內(nèi)容如下:

<explode  
  xmlns:android="http://schemas.android.com/apk/res/android"   
  android:duration="300" />

其中duration表示Explode動畫持續(xù)時間,由于是Activity之間的切換,最好不要把動畫時間設(shè)置過大,一般取200~500毫秒比較合適。

我們看看效果吧~


3.2 Slide效果

即滑動效果,使用Slide跟Explode類似,都是在res/transition目錄下新建一個xml文件(如slide.xml),內(nèi)容如下:


圖呢??

其中,slideEdge表示起始滑動的側(cè)邊位置,end表示右側(cè),start表示左側(cè),top表示頂部,bottom表示底側(cè),各種效果你可以親自試試~,一起看看滑動效果吧:


GIF 效果看的比較死板,可以下載我的源碼實際運行一下~

如果你不希望頂部的狀態(tài)欄以及底部的導(dǎo)航欄一起執(zhí)行動畫,可以在xml中指定:


3.3 Fade效果

Fade效果即淡化效果,使用淡化效果依然是很簡單,在res/transition目錄下新建一個xml文件(如fade.xml),內(nèi)容如下:

<fade    
   xmlns:android="http://schemas.android.com/apk/res/android" 
   android:duration="300" />

Fade效果就是將View逐步淡化,這里不再貼效果啦,想看效果的可以下載我的源碼運行看看~

3.4 Shared Element效果

即共享元素效果,與前面幾種效果不同的是,共享元素效果是將前面一個Activity的某個子View與后面一個Activity的某個子View之間有過渡效果,我們先看看動態(tài)圖感受一下:

從動態(tài)圖中看到,第一個Activity的小綠色方塊到第二個Activity大綠色方塊有個過渡效果~

接下來我們重點看看如何實現(xiàn)這個效果。

如何實現(xiàn)Shared Element效果

1.將兩個Activity中需要過渡的View加上Android:transitionName屬性

兩個View的android:transitionName屬性取值要一致,比如:
第一個Activity布局:

第二個Activity布局:

兩個綠色的View都添加android:transitionName屬性,并且取名一致。

2.調(diào)用startActivity

ActivityOptions的makeSceneTransitionAnimation函數(shù)第一個參數(shù)Activity沒啥解釋的,第二個參數(shù)就是第一個Activity中的View對象,第三個參數(shù)就是兩個Activity的View的 android:transitionName屬性的值。


現(xiàn)在就可以實現(xiàn)這種Shared Element效果啦,但是可能你會想實現(xiàn)同時讓兩個View有這樣的效果,可是makeSceneTransitionAnimation函數(shù)卻只能讓我們設(shè)置一個View和一個transitionName屬性。

如何添加多個呢?

接下來我們一起學(xué)習(xí)讓多個View同時有切換效果。
除了需要將兩個Activity中需要過渡的View對應(yīng)取相同的名稱外,還需將需要過渡的View和transitionName取值對應(yīng)的String這兩個對象封裝到一個Pair對象中:

然后調(diào)用ActivityOptionsCompat類的makeSceneTransitionAnimation的另一個重載函數(shù):

makeSceneTransitionAnimation(Activity activity,  Pair<View, String>... sharedElements)

第一個參數(shù)不解釋,后面參數(shù)為不定長度的形參,即你可以傳遞任意多個Pair對象。

最后調(diào)用startActivity

ActivityCompat.startActivity(this, intent, transitionActivityOptions.toBundle());

說了這么多步驟,我們來看看效果吧~

自定義 Shared Element切換動畫

如果你對內(nèi)置的 Shared Element還不夠滿意,你還可以定制View的過渡切換效果。

步驟如下

1.創(chuàng)建一個View的過渡移動的軌跡路徑PathMotion類

我們可以創(chuàng)建ArcMotion對象,ArcMotion是PathMotion子類,是個曲線路徑。想要了解更多ArcMotion可以查看:
ArcMotion官方文檔

ArcMotion arcMotion = new ArcMotion();
arcMotion.setMinimumHorizontalAngle(50f);
arcMotion.setMinimumVerticalAngle(50f);

2.定義ChangeBounds類

我們自定義一個繼承ChangeBounds的類,主要重寫createAnimator函數(shù),即創(chuàng)建你要執(zhí)行的動畫。這個函數(shù)由3個參數(shù):

  • ViewGroup sceneRoot:屏幕根View,即DecorView,第二個Activity的DecorView

  • TransitionValues startValues :屬性動畫的起始屬性值,TransitionValues 對象內(nèi)部有各Map類型的屬性values,用于保存需要執(zhí)行屬性動畫的屬性。這個里面的屬性值是在函數(shù)captureStartValues里放置,因此你可以重寫captureStartValues函數(shù),并把你自定義的屬性動畫中的屬性放進(jìn)去。

  • TransitionValues endValues:與startValues類似,表示屬性動畫結(jié)束時的屬性值。可以通過重寫captureEndValues函數(shù),并把你自定義的屬性動畫里面的最終屬性值放進(jìn)去。

我們先看一個最簡單的示例:


看看效果吧~

最后5.0這部分借鑒(copy)于兩位大神,僅作為個人學(xué)習(xí)參考資料,如有侵權(quán)告知立刪除,附源圖如下

5.0部分原創(chuàng)公眾號
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,923評論 6 535
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,740評論 3 420
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,856評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,175評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,931評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,321評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,383評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,533評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,082評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,891評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,618評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,319評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,732評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,987評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,794評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,076評論 2 375

推薦閱讀更多精彩內(nèi)容