酷炫的Activity切換動(dòng)畫(huà)眯搭,打造更好的用戶體驗(yàn)

我的CSDN博客同步發(fā)布:酷炫的Activity切換動(dòng)畫(huà)脸爱,打造更好的用戶體驗(yàn)

轉(zhuǎn)載請(qǐng)注明出處:【huachao1001的簡(jiǎn)書(shū):http://www.reibang.com/users/0a7e42698e4b/latest_articles】

毫無(wú)疑問(wèn)瘪阁,動(dòng)畫(huà)效果能提高用戶體驗(yàn)类浪。我們平時(shí)使用最多的動(dòng)畫(huà)基本上是屬性動(dòng)畫(huà)和補(bǔ)間動(dòng)畫(huà)了臭蚁,屬性動(dòng)畫(huà)很強(qiáng)最铁,基本能定制我們想要的動(dòng)畫(huà),但是你是否知道垮兑,API 21(5.0)后系統(tǒng)內(nèi)置了Activity之間的切換動(dòng)畫(huà)冷尉,而且非常酷炫系枪,今天我跟大家一起分享一下雀哨。我們知道,在兩個(gè)Activity之間切換私爷,我們一般會(huì)寫(xiě)出類似下面的代碼:

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

在API 21以后雾棺,我們可以使用內(nèi)置的Activity切換動(dòng)畫(huà)啦。但是這樣也就意味著只能兼容5.0之后的系統(tǒng)衬浑,我們先看一個(gè)效果圖來(lái)壓壓驚:

Activity之間切換效果圖

先看看第一個(gè)Activity捌浩,退出時(shí)用的是Explode效果,第二個(gè)Activity進(jìn)入時(shí)用的是Slide效果工秩。這些效果無(wú)需我們自己去實(shí)現(xiàn)尸饺,都是內(nèi)置的效果,我們所編寫(xiě)的代碼幾乎為零助币,接下來(lái)我們一一看看內(nèi)置了哪些效果浪听。

1 使用內(nèi)置Activity之間切換動(dòng)畫(huà)代碼步驟

Activity之間的切換期間,對(duì)于某個(gè)Activity來(lái)說(shuō)眉菱,無(wú)非就是“進(jìn)入”和“退出”兩種情景下的動(dòng)畫(huà)迹栓。而“進(jìn)入”分為“第一次進(jìn)入Activity”和“返回當(dāng)前Activity”這兩種情況。另外系統(tǒng)還提供了一種動(dòng)畫(huà)俭缓,即共享元素克伊,這是讓兩個(gè)Activity中的View有個(gè)過(guò)渡切換的效果叉抡。執(zhí)行動(dòng)畫(huà)的狀態(tài)如下所示:

enter:用于決定第一次打開(kāi)當(dāng)前Activity時(shí)的動(dòng)畫(huà)
exit : 用于決定退出當(dāng)前Activity時(shí)的動(dòng)畫(huà)
reenter: 用于決定如果當(dāng)前Activity已經(jīng)打開(kāi)過(guò),并且再次打開(kāi)該Activity時(shí)的動(dòng)畫(huà)
shared elements:用于決定在兩個(gè)Activity之間切換時(shí)答毫,指定兩個(gè)Activity中對(duì)應(yīng)的View的過(guò)渡效果

那么應(yīng)該怎么去使用Activity切換動(dòng)畫(huà)呢褥民?我們看看使用步驟:
1.首先在setContentView()之前執(zhí)行,用于告訴Window頁(yè)面切換需要使用動(dòng)畫(huà)

getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

2.接下來(lái)就是加載切換動(dòng)畫(huà)
其中R.transition.explode就是要執(zhí)行的動(dòng)畫(huà)洗搂,是在res/transition目錄下的xml文件消返,我們使用的是系統(tǒng)內(nèi)置的Explode效果動(dòng)畫(huà),關(guān)于怎么去寫(xiě)explode.xml耘拇,我們接下來(lái)小節(jié)去講解撵颊。

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

3.告訴Window,當(dāng)前的Activity在什么情況下使用上面的動(dòng)畫(huà)
上面我們創(chuàng)建好了切換動(dòng)畫(huà)惫叛,接下來(lái)就是要告訴當(dāng)前窗口倡勇,在什么情況下去使用動(dòng)畫(huà)效果啦,你可以根據(jù)你的需求在不同的切換情景中選擇不同的效果:

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

當(dāng)然了嘉涌,你也可以不使用代碼的方式妻熊,直接在你使用的主題<style>標(biāo)簽里添加類似如下代碼:

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

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

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

整體使用步驟就是以上這些,是不是很簡(jiǎn)單警医?接下來(lái)我們?nèi)W(xué)習(xí)如何使用內(nèi)置動(dòng)畫(huà)~

2 Explode效果

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

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

其中duration表示Explode動(dòng)畫(huà)持續(xù)時(shí)間侈玄,由于是Activity之間的切換,最好不要把動(dòng)畫(huà)時(shí)間設(shè)置過(guò)大吟温,一般取200~500毫秒比較合適序仙。
我們看看效果吧~

Explode效果

3 Slide效果

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

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

其中洋丐,slideEdge表示起始滑動(dòng)的側(cè)邊位置呈昔,end表示右側(cè),start表示左側(cè)友绝,top表示頂部堤尾,bottom表示底側(cè),各種效果你可以親自試試~迁客,一起看看滑動(dòng)效果吧

Slide效果

GIF 效果看的比較死板郭宝,可以下載我的源碼實(shí)際運(yùn)行一下~

如果你不希望頂部的狀態(tài)欄以及底部的導(dǎo)航欄一起執(zhí)行動(dòng)畫(huà)辞槐,可以在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效果即淡化效果,使用淡化效果依然是很簡(jiǎn)單粘室,在res/transition目錄下新建一個(gè)xml文件(如fade.xml)榄檬,內(nèi)容如下:

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

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

5 Shared Element效果

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

Shared Element效果

從動(dòng)態(tài)圖中看到舱殿,第一個(gè)Activity的小綠色方塊到第二個(gè)Activity大綠色方塊有個(gè)過(guò)渡效果~

接下來(lái)我們看看如何實(shí)現(xiàn)這個(gè)效果:

1.將兩個(gè)Activity中需要過(guò)渡的View加上android:transitionName屬性

兩個(gè)View的android:transitionName屬性取值要一致,比如:
第一個(gè)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>

第二個(gè)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>

兩個(gè)綠色的View都添加android:transitionName屬性险掀,并且取名一致沪袭。

2.調(diào)用startActivity
ActivityOptionsmakeSceneTransitionAnimation函數(shù)第一個(gè)參數(shù)Activity沒(méi)啥解釋的,第二個(gè)參數(shù)就是第一個(gè)Activity中的View對(duì)象樟氢,第三個(gè)參數(shù)就是兩個(gè)ActivityViewandroid:transitionName屬性的值冈绊。

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

現(xiàn)在就可以實(shí)現(xiàn)這種Shared Element效果啦,但是可能你會(huì)想實(shí)現(xiàn)同時(shí)讓兩個(gè)View有這樣的效果埠啃,可是makeSceneTransitionAnimation函數(shù)卻只能讓我們?cè)O(shè)置一個(gè)View和一個(gè)transitionName屬性焚碌。如何添加多個(gè)呢?接下來(lái)我們一起學(xué)習(xí)讓多個(gè)View同時(shí)有切換效果霸妹。

除了需要將兩個(gè)Activity中需要過(guò)渡的View對(duì)應(yīng)取相同的名稱外十电,還需將需要過(guò)渡的View和transitionName取值對(duì)應(yīng)的String這兩個(gè)對(duì)象封裝到一個(gè)Pair對(duì)象中:

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

然后調(diào)用ActivityOptionsCompat類的makeSceneTransitionAnimation的另一個(gè)重載函數(shù)makeSceneTransitionAnimation(Activity activity, Pair<View, String>... sharedElements),第一個(gè)參數(shù)不解釋叹螟,后面參數(shù)為不定長(zhǎng)度的形參鹃骂,即你可以傳遞任意多個(gè)Pair對(duì)象。

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

最后調(diào)用startActivity

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

說(shuō)了這么多步驟罢绽,我們來(lái)看看效果吧~


多個(gè)子View的過(guò)渡效果

5.1 自定義 Shared Element切換動(dòng)畫(huà)

如果你對(duì)內(nèi)置的 Shared Element還不夠滿意畏线,你還可以定制View的過(guò)渡切換效果。步驟如下:

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

我們可以創(chuàng)建ArcMotion對(duì)象良价,ArcMotion是PathMotion子類寝殴,是個(gè)曲線路徑。想要了解更多ArcMotion可以查看【ArcMotion官方文檔】

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

2.定義ChangeBounds類

我們自定義一個(gè)繼承ChangeBounds的類明垢,主要重寫(xiě)createAnimator函數(shù)蚣常,即創(chuàng)建你要執(zhí)行的動(dòng)畫(huà)。這個(gè)函數(shù)由3個(gè)參數(shù):

1.ViewGroup sceneRoot:屏幕根View痊银,即DecorView抵蚊,第二個(gè)Activity的DecorView。

  1. TransitionValues startValues :屬性動(dòng)畫(huà)的起始屬性值,TransitionValues 對(duì)象內(nèi)部有各Map類型的屬性values贞绳,用于保存需要執(zhí)行屬性動(dòng)畫(huà)的屬性谷醉。這個(gè)里面的屬性值是在函數(shù)captureStartValues里放置,因此你可以重寫(xiě)captureStartValues函數(shù)冈闭,并把你自定義的屬性動(dòng)畫(huà)中的屬性放進(jìn)去俱尼。
  2. TransitionValues endValues :與startValues類似,表示屬性動(dòng)畫(huà)結(jié)束時(shí)的屬性值萎攒『畔裕可以通過(guò)重寫(xiě)captureEndValues函數(shù),并把你自定義的屬性動(dòng)畫(huà)里面的最終屬性值放進(jìn)去躺酒。

我們先看一個(gè)最簡(jiǎn)單的示例:

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切換

最后押蚤,再獻(xiàn)上源碼:http://download.csdn.net/detail/huachao1001/9550440

參考資料:

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市羹应,隨后出現(xiàn)的幾起案子揽碘,更是在濱河造成了極大的恐慌,老刑警劉巖园匹,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雳刺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡裸违,警方通過(guò)查閱死者的電腦和手機(jī)掖桦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)供汛,“玉大人枪汪,你說(shuō)我怎么就攤上這事≌颍” “怎么了雀久?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)趁舀。 經(jīng)常有香客問(wèn)我赖捌,道長(zhǎng),這世上最難降的妖魔是什么矮烹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任越庇,我火速辦了婚禮,結(jié)果婚禮上奉狈,老公的妹妹穿的比我還像新娘卤唉。我一直安慰自己,他們只是感情好嘹吨,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布搬味。 她就那樣靜靜地躺著境氢,像睡著了一般蟀拷。 火紅的嫁衣襯著肌膚如雪碰纬。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天问芬,我揣著相機(jī)與錄音悦析,去河邊找鬼。 笑死此衅,一個(gè)胖子當(dāng)著我的面吹牛强戴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挡鞍,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼骑歹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了墨微?” 一聲冷哼從身側(cè)響起道媚,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎翘县,沒(méi)想到半個(gè)月后最域,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锈麸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年镀脂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忘伞。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡薄翅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出氓奈,到底是詐尸還是另有隱情匿刮,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布探颈,位于F島的核電站熟丸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏伪节。R本人自食惡果不足惜光羞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怀大。 院中可真熱鬧纱兑,春花似錦、人聲如沸化借。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至铐炫,卻和暖如春垒手,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背倒信。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工科贬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鳖悠。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓榜掌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親乘综。 傳聞我的和親對(duì)象是個(gè)殘疾皇子憎账,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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