酷炫的Activity切換動畫,打造更好的用戶體驗

我的CSDN博客同步發布:酷炫的Activity切換動畫,打造更好的用戶體驗

轉載請注明出處:【huachao1001的簡書:http://www.lxweimin.com/users/0a7e42698e4b/latest_articles】

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

Intent intent=new Intent(this,SecondActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);

在API 21以后,我們可以使用內置的Activity切換動畫啦。但是這樣也就意味著只能兼容5.0之后的系統,我們先看一個效果圖來壓壓驚:

Activity之間切換效果圖

先看看第一個Activity,退出時用的是Explode效果,第二個Activity進入時用的是Slide效果。這些效果無需我們自己去實現,都是內置的效果,我們所編寫的代碼幾乎為零,接下來我們一一看看內置了哪些效果。

1 使用內置Activity之間切換動畫代碼步驟

Activity之間的切換期間,對于某個Activity來說,無非就是“進入”和“退出”兩種情景下的動畫。而“進入”分為“第一次進入Activity”和“返回當前Activity”這兩種情況。另外系統還提供了一種動畫,即共享元素,這是讓兩個Activity中的View有個過渡切換的效果。執行動畫的狀態如下所示:

enter:用于決定第一次打開當前Activity時的動畫
exit : 用于決定退出當前Activity時的動畫
reenter: 用于決定如果當前Activity已經打開過,并且再次打開該Activity時的動畫
shared elements:用于決定在兩個Activity之間切換時,指定兩個Activity中對應的View的過渡效果

那么應該怎么去使用Activity切換動畫呢?我們看看使用步驟:
1.首先在setContentView()之前執行,用于告訴Window頁面切換需要使用動畫

getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

2.接下來就是加載切換動畫
其中R.transition.explode就是要執行的動畫,是在res/transition目錄下的xml文件,我們使用的是系統內置的Explode效果動畫,關于怎么去寫explode.xml,我們接下來小節去講解。

  Transition explode = TransitionInflater.from(this).inflateTransition(R.transition.explode);

3.告訴Window,當前的Activity在什么情況下使用上面的動畫
上面我們創建好了切換動畫,接下來就是要告訴當前窗口,在什么情況下去使用動畫效果啦,你可以根據你的需求在不同的切換情景中選擇不同的效果:

//退出時使用
getWindow().setExitTransition(explode);
//第一次進入時使用
getWindow().setEnterTransition(explode);
//再次進入時使用
getWindow().setReenterTransition(explode); 

當然了,你也可以不使用代碼的方式,直接在你使用的主題<style>標簽里添加類似如下代碼:

<item name="android:windowExitTransition">@transition/explode</item>
<item name="android:windowEnterAnimation">@transition/explode</item>
<item name="android:windowReenterTransition">@transition/explode</item>

4.調用startActivity
跟我們之前使用的startActivity(Intent intent);不同,這里多了一個參數Bundle,我們是先通過makeSceneTransitionAnimation函數創建一個ActivityOptions對象,再將其轉為Bundle對象:

startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

整體使用步驟就是以上這些,是不是很簡單?接下來我們去學習如何使用內置動畫~

2 Explode效果

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

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

其中duration表示Explode動畫持續時間,由于是Activity之間的切換,最好不要把動畫時間設置過大,一般取200~500毫秒比較合適。
我們看看效果吧~

Explode效果

3 Slide效果

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

<slide xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:interpolator/decelerate_cubic"
    android:slideEdge="end"/>

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

Slide效果

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

如果你不希望頂部的狀態欄以及底部的導航欄一起執行動畫,可以在xml中指定:

<slide xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:interpolator/decelerate_cubic"
    android:slideEdge="end">
    <targets>
        <target android:excludeId="@android:id/navigationBarBackground" />
        <target android:excludeId="@android:id/statusBarBackground" />
    </targets>
</slide>

4 Fade效果

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

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

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

5 Shared Element效果

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

Shared Element效果

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

接下來我們看看如何實現這個效果:

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

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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/firstSharedView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#00cc00"
        android:onClick="onClick"
        android:transitionName="sharedView" />
</RelativeLayout>

第二個Activity布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_alignParentBottom="true"
        android:background="#00cc00"
        android:onClick="onClick"
        android:transitionName="sharedView" />

</RelativeLayout>

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

2.調用startActivity
ActivityOptionsmakeSceneTransitionAnimation函數第一個參數Activity沒啥解釋的,第二個參數就是第一個Activity中的View對象,第三個參數就是兩個ActivityViewandroid:transitionName屬性的值。

 startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, firstSharedView, "sharedView").toBundle());
   

現在就可以實現這種Shared Element效果啦,但是可能你會想實現同時讓兩個View有這樣的效果,可是makeSceneTransitionAnimation函數卻只能讓我們設置一個View和一個transitionName屬性。如何添加多個呢?接下來我們一起學習讓多個View同時有切換效果。

除了需要將兩個Activity中需要過渡的View對應取相同的名稱外,還需將需要過渡的View和transitionName取值對應的String這兩個對象封裝到一個Pair對象中:

 Pair first = new Pair<>(firstSharedView, ViewCompat.getTransitionName(firstSharedView));
 
 Pair second = new Pair<>(secondSharedView, ViewCompat.getTransitionName(secondSharedView));

然后調用ActivityOptionsCompat類的makeSceneTransitionAnimation的另一個重載函數makeSceneTransitionAnimation(Activity activity, Pair<View, String>... sharedElements),第一個參數不解釋,后面參數為不定長度的形參,即你可以傳遞任意多個Pair對象。

 ActivityOptionsCompat transitionActivityOptions =
      ActivityOptionsCompat.makeSceneTransitionAnimation(this, first, second);

最后調用startActivity

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

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


多個子View的過渡效果

5.1 自定義 Shared Element切換動畫

如果你對內置的 Shared Element還不夠滿意,你還可以定制View的過渡切換效果。步驟如下:

1.創建一個View的過渡移動的軌跡路徑PathMotion類

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

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

2.定義ChangeBounds類

我們自定義一個繼承ChangeBounds的類,主要重寫createAnimator函數,即創建你要執行的動畫。這個函數由3個參數:

1.ViewGroup sceneRoot:屏幕根View,即DecorView,第二個Activity的DecorView。

  1. TransitionValues startValues :屬性動畫的起始屬性值,TransitionValues 對象內部有各Map類型的屬性values,用于保存需要執行屬性動畫的屬性。這個里面的屬性值是在函數captureStartValues里放置,因此你可以重寫captureStartValues函數,并把你自定義的屬性動畫中的屬性放進去。
  2. TransitionValues endValues :與startValues類似,表示屬性動畫結束時的屬性值。可以通過重寫captureEndValues函數,并把你自定義的屬性動畫里面的最終屬性值放進去。

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

package com.hc.util;

import android.animation.Animator;
import android.transition.ChangeBounds;
import android.transition.TransitionValues;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;


public class CustomChangeBounds extends ChangeBounds {

 @Override
  public Animator createAnimator(final ViewGroup sceneRoot,
                                 TransitionValues startValues,
                                 final TransitionValues endValues) {
      Animator changeBounds = super.createAnimator(sceneRoot, startValues, endValues);
      if (startValues == null || endValues == null || changeBounds == null) 
          return null;

      changeBounds.setDuration(300);
      changeBounds.setInterpolator(AnimationUtils.loadInterpolator(sceneRoot.getContext(),
              android.R.interpolator.fast_out_slow_in));
      return changeBounds;
  }

}

看看效果吧~

自定義Activity切換

最后,再獻上源碼:http://download.csdn.net/detail/huachao1001/9550440

參考資料:

https://labs.ribot.co.uk/exploring-meaningful-motion-on-android-1cd95a4bc61d#.cf6pub9xu
https://github.com/hitherejoe/animate

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

推薦閱讀更多精彩內容