1. 程式人生 > >安卓專案實戰之設定Activity跳轉動畫的5種實現方式

安卓專案實戰之設定Activity跳轉動畫的5種實現方式

前言

在介紹activity的切換動畫之前我們先來說明一下實現切換activity的兩種方式:
1,呼叫startActivity方法啟動一個新的Activity並跳轉其頁面
2,呼叫finish方法銷燬當前的Activity返回上一個Activity介面

當呼叫startActivity方法的時候啟動一個新的activity,這時候就涉及到了舊的Activity的退出動畫和新的Activity的顯示動畫;
當呼叫finish方法的時候,銷燬當前Acitivity,就涉及到了當前Activity的退出動畫和前一個Activity的顯示動畫;

所以我們的activity跳轉動畫是分為兩個部分的:一個Activity的銷燬動畫與一個Activity的顯示動畫,知道這些之後我們開始今天跳轉動畫的5種實現方式的講解,其中後面介紹的三種方式都是Android 5.0以後的api支援的。

本文轉載自 https://blog.csdn.net/qq_23547831/article/details/51821159

(一)使用overridePendingTransition方法實現Activity跳轉動畫

overridePendingTransition方法是Activity中提供的Activity跳轉動畫方法,通過該方法可以實現Activity跳轉時的動畫效果。下面我們就將通過一個簡單的例子看一下如何通過overridePendingTransition方法實現Activity的切換動畫。

demo例子中我們實現了Activity a中有一個點選按鈕,點選按鈕實現跳轉Activity b的邏輯,具體程式碼如下:

/**
 * 點選按鈕實現跳轉邏輯
 */
button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /**
                 * 在呼叫了startActivity方法之後立即呼叫overridePendingTransition方法
                 */
                Intent intent = new Intent(MainActivity.
this, SecondActivity.class); startActivity(intent); overridePendingTransition(R.anim.slide_in_left, R.anim.slide_in_left); } });

可以看到我們在呼叫了startActivity方法之後又執行了overridePendingTransition方法,而在overridePendingTransition方法中傳遞了兩個動畫布局檔案,我們首先看一下這裡的動畫檔案具體是怎麼實現的:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shareInterpolator="false"
    Android:zAdjustment="top">
    <translate
        Android:duration="200"
        Android:fromXDelta="-100.0%p"
        Android:toXDelta="0.0" />
</set>

這裡的overridePendingTransition方法傳遞的是兩個動畫檔案id,第一個引數是需要開啟的Activity進入時的動畫,第二個引數是需要關閉的Activity離開時的動畫。這樣我們執行了這段程式碼之後在跳轉Activity的時候就展示了動畫效果:
在這裡插入圖片描述
關於overridePendingTransition方法我們再強調以下幾點:
1,overridePendingTransition方法需要在startAtivity方法或者是finish方法呼叫之後執行
2,引數enterAnim表示的是從Activity a跳轉到Activity b,進入b時的動畫效果
3,引數exitAnim表示的是從Activity a跳轉到Activity b,離開a時的動過效果
4,若進入b或者是離開a時不需要動畫效果,則可以傳值為0

(二)使用style的方式定義Activity的切換動畫

1,定義Application的theme,一般我們建立的應用預設都會配置一個theme主題的:

<!-- 系統Application定義 -->
<application
        Android:allowBackup="true"
        Android:icon="@mipmap/ic_launcher"
        Android:label="@string/app_name"
        Android:supportsRtl="true"
        Android:theme="@style/AppTheme">

2,定義具體的AppTheme樣式:

<!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        
        <item name="Android:windowAnimationStyle">@style/activityAnim</item>
    </style>


<!-- 使用style方式定義activity切換動畫 -->
    <style name="activityAnim">
        <item name="Android:activityOpenEnterAnimation">@anim/slide_in_top</item>
        <item name="Android:activityOpenExitAnimation">@anim/slide_in_top</item>
    </style>

這裡的windowAnimationStyle就是我們定義Activity切換動畫的style。而@anim/slide_in_top就是我們定義的動畫檔案,也就是說通過為Appliation設定style,然後為windowAnimationStyle設定動畫檔案就可以全域性的為Activity的跳轉配置動畫效果。
在windowAnimationStyle中一共可以定義四種動畫效果,如下所示,上面只用到了前兩個:

activityOpenEnterAnimation // 用於設定開啟新的Activity並進入新的Activity展示的動畫
activityOpenExitAnimation  // 用於設定開啟新的Activity並銷燬之前的Activity展示的動畫
activityCloseEnterAnimation  // 用於設定關閉當前Activity進入上一個Activity展示的動畫
activityCloseExitAnimation  // 用於設定關閉當前Activity時展示的動畫

3,測試程式碼,實現activity切換操作:

/**
         * 點選按鈕,實現Activity的跳轉操作
         * 通過定義style的方式實現activity的跳轉動畫
         */
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /**
                 * 普通的Intent跳轉Activity實現
                 */
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });

此時我們只需正常實現跳轉邏輯,就會發現我們在style中設定的切換動畫生效了。

(三)使用ActivityOptions切換動畫實現Activity跳轉動畫

上面我們講解的通過overridePendingTransition方法基本上可以滿足我們日常中對Activity跳轉動畫的需求了,但是MD風格出來之後,overridePendingTransition這種老舊、生硬的方式怎麼能適合我們的MD風格的App呢?好在google在新的sdk中給我們提供了另外一種Activity的過度動畫——ActivityOptions。並且提供了相容包——ActivityOptionsCompat。ActivityOptionsCompat是一個靜態類,提供了相應的Activity跳轉動畫效果,通過其可以實現不少炫酷的動畫效果。
1,在跳轉的Activity中設定contentFeature,即在呼叫setContentView方法前新增下面幾行程式碼:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 設定activity的視窗屬性為contentFeature,即可使用切換動畫
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        Transition explode = TransitionInflater.from(this).inflateTransition(Android.R.transition.explode);
        // 此處獲取了系統內建的explode動畫效果設定給了activity的視窗物件
        getWindow().setEnterTransition(explode);

        setContentView(R.layout.activity_three);
    }

2,在startActivity執行跳轉邏輯的時候呼叫startActivity的重寫方法,執行ActivityOptions.makeSceneTransitionAnimation方法:

/**
         * 點選按鈕,實現Activity的跳轉操作
         * 通過Android5.0及以上程式碼的方式實現activity的跳轉動畫
         */
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, ThreeActivity.class);
                startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle());
            }
        });

這裡我們呼叫了startActivity的過載方法:

public void startActivity(Intent intent, @Nullable Bundle options)

並且我們傳入了ActivityOptions.makeSceneTransitionAnimation,該方法表示將Activity a平滑的切換到Activity b,其還有幾個過載方法可以指定相關的View,即以View為焦點平滑的從Activity a切換到Activity b。

呼叫這段程式碼之後我們activity跳轉的時候就展示出了動畫效果:
在這裡插入圖片描述

(四)使用ActivityOptions之後內建的動畫效果通過style的方式

1,編寫過渡動畫檔案
首先我們需要在Application專案res目錄下新建一個transition目錄,然後建立資原始檔,然後使用這些系統自帶的過渡動畫效果,這裡設定了過度時長為300ms。

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

2,

<!-- 系統Application定義 -->
<application
        Android:allowBackup="true"
        Android:icon="@mipmap/ic_launcher"
        Android:label="@string/app_name"
        Android:supportsRtl="true"
        Android:theme="@style/AppTheme">

在Application的theme對應的AppTheme的style樣式中指定過渡動畫效果為我們剛剛定義的過渡動畫檔案:

<!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>

        <item name="Android:windowEnterTransition">@transition/activity_explode</item>
        <item name="Android:windowExitTransition">@transition/activity_explode</item>
    </style>

3,執行跳轉邏輯:

/**
         * 點選按鈕,實現Activity的跳轉操作
         * 通過Android5.0及以上style的方式實現activity的跳轉動畫
         */
        button4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /**
                 * 呼叫ActivityOptions.makeSceneTransitionAnimation實現過度動畫
                 */
                Intent intent = new Intent(MainActivity.this, FourActivity.class);
                startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle());
            }
        });

這樣執行之後也可以展示出Activity跳轉過度動畫了,其和通過程式碼方式實現的效果是類似的,只是少了在setContentView方法呼叫前的幾句程式碼的新增,而且這種動畫效果是全域性的。

(五)使用ActivityOptions動畫共享元件的方式實現跳轉Activity動畫

這裡的共享元件動畫效果是指在前面一個Activity的某個子View與後面一個Activity的某個子View之間建立過渡效果,然後在這種過度效果下同時實現Activity的跳轉操作。那麼如何實現兩個元件View之間實現過渡效果呢?
1,定義共享關聯元件1
為Activity a中的button按鈕設定transitionName屬性,記住該屬性值後面會用到:

<Button
        Android:id="@+id/button5"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_below="@+id/button4"
        Android:layout_marginTop="10dp"
        Android:layout_marginRight="10dp"
        Android:layout_marginLeft="10dp"
        Android:text="元件過度動畫"
        Android:background="@color/colorPrimary"
        Android:transitionName="shareNames"
        />

2,定義共享關聯元件2
同樣的在Activity b的佈局檔案中為需要和Activity a中button建立關聯的元件也定義transitionName屬性,並且這兩個元件的transitionName屬性的值必須是相同的,這樣這兩個元件相當於有了過度對應關係,如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/activity_second"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:gravity="center_horizontal"
    Android:orientation="vertical"
    Android:transitionName="shareNames"
    >

    <TextView
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="@color/colorAccent"
        Android:layout_marginTop="10dp"
        Android:layout_marginBottom="10dp"
        />

</LinearLayout>

3,呼叫startActivity執行跳轉動畫

/**
         * 點選按鈕,實現Activity的跳轉操作
         * 通過Android5.0及以上共享元件的方式實現activity的跳轉動畫
         */
        button5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, FiveActivity.class);
                startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, button5, "shareNames").toBundle());
            }
        });

需要說明的是這裡呼叫的ActivityOptions.makeSceneTransitionAnimation方法,傳遞了三個引數,其中第一個引數為context物件,第二個引數為啟動Activity的共享元件,第三個引數為啟動Activity的共享元件transitionName屬性值。

這樣經過呼叫之後我們就實現了從Activity a跳轉到Activity b的時候a中的元件到b中元件的過度效果:
在這裡插入圖片描述