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

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

轉(zhuǎn)載請注明出處:【huachao1001的簡書:http://www.itdecent.cn/users/0a7e42698e4b/latest_articles】

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

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

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

Activity之間切換效果圖

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

1 使用內(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切換動畫呢?我們看看使用步驟:
1.首先在setContentView()之前執(zhí)行,用于告訴Window頁面切換需要使用動畫

getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

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

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

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

//退出時使用
getWindow().setExitTransition(explode);
//第一次進(jìn)入時使用
getWindow().setEnterTransition(explode);
//再次進(jìn)入時使用
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);不同,這里多了一個參數(shù)Bundle,我們是先通過makeSceneTransitionAnimation函數(shù)創(chuàng)建一個ActivityOptions對象,再將其轉(zhuǎn)為Bundle對象:

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

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

2 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毫秒比較合適。
我們看看效果吧~

Explode效果

3 Slide效果

即滑動效果,使用Slide跟Explode類似,都是在res/transition目錄下新建一個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表示起始滑動的側(cè)邊位置,end表示右側(cè),start表示左側(cè),top表示頂部,bottom表示底側(cè),各種效果你可以親自試試~,一起看看滑動效果吧

Slide效果

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

如果你不希望頂部的狀態(tài)欄以及底部的導(dǎo)航欄一起執(zhí)行動畫,可以在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),內(nèi)容如下:

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

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

5 Shared Element效果

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

Shared Element效果

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

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

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.調(diào)用startActivity
ActivityOptionsmakeSceneTransitionAnimation函數(shù)第一個參數(shù)Activity沒啥解釋的,第二個參數(shù)就是第一個Activity中的View對象,第三個參數(shù)就是兩個ActivityViewandroid:transitionName屬性的值。

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

現(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對象中:

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

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

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

最后調(diào)用startActivity

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

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


多個子View的過渡效果

5.1 自定義 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ù):

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

  1. TransitionValues startValues :屬性動畫的起始屬性值,TransitionValues 對象內(nèi)部有各Map類型的屬性values,用于保存需要執(zhí)行屬性動畫的屬性。這個里面的屬性值是在函數(shù)captureStartValues里放置,因此你可以重寫captureStartValues函數(shù),并把你自定義的屬性動畫中的屬性放進(jìn)去。
  2. TransitionValues endValues :與startValues類似,表示屬性動畫結(jié)束時的屬性值??梢酝ㄟ^重寫captureEndValues函數(shù),并把你自定義的屬性動畫里面的最終屬性值放進(jì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)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容