啟動畫面

從 Android 12 開始,SplashScreen API 可讓應用程式以動畫啟動,包括啟動時的應用程式內動態、顯示應用程式圖示的啟動畫面,以及應用程式本身的轉換。SplashScreenWindow,因此涵蓋 Activity

圖 1.啟動畫面。

啟動畫面體驗在每次應用程式啟動時提供標準設計元素,但您也可以自訂此設定,讓應用程式保有獨特的品牌宣傳元素。

除了使用 SplashScreen 平台 API 之外,您亦可使用 SplashScreen 相容性程式庫,其中也包含了 SplashScreen API。

啟動畫面的運作方式

如果使用者在應用程式程序未執行 (冷啟動) 或 Activity 未建立 (暖啟動) 的情況下啟動應用程式,就會發生以下事件:

  1. 系統會使用您定義的主題和任何動畫顯示啟動畫面。

  2. 應用程式準備就緒後,系統就會關閉啟動畫面並顯示應用程式。

熱啟動期間一律不會顯示啟動畫面。

啟動畫面的元素和機制

啟動畫面的元素是由 Android 資訊清單檔案中的 XML 資源檔案定義。每個元素都有淺色和深色模式版本。

啟動畫面的可自訂元素包含應用程式圖示、圖示背景和視窗背景:

顯示啟動畫面所含元素的圖片
圖 2. 啟動畫面的可自訂元素。

請參考圖 2 所示的下列元素:

1 應用程式圖示必須是向量可繪項目。可以是靜態或動畫。雖然動畫沒有持續時間限制,但建議不要超過 1,000 毫秒。預設圖示為啟動器圖示。

2 圖示背景是選用項目,可視需要在圖示和視窗背景之間進行更對比。如果使用自動調整圖示,當視窗背景的對比度夠高時,就會顯示其背景。

3 與自動調整圖示一樣,有三分之一的前景會遭到遮蓋。

4 視窗背景包含單一不透明顏色。如果已設定視窗背景且為純色,當未設定屬性時,則根據預設使用此背景。

啟動畫面尺寸

啟動畫面圖示使用的規格與自動調整圖示相同,如下所示:

  • 品牌圖片:尺寸必須為 200×80 dp。
  • 包含圖示背景的應用程式圖示:必須為 240×240 dp,且符合直徑 160 dp 的圓形範圍。
  • 不含圖示背景的應用程式圖示:大小必須為 288 × 288 dp,且符合直徑為 192 dp 的圓形。

舉例來說,如果圖片的原尺寸為 300×300 dp,圖示應符合直徑 200 dp 的圓環。圓形外的所有內容都會變為隱藏 (遮蓋)。

這張圖片顯示實心和透明背景的各種圖示尺寸
圖 3. 分別針對實心和透明背景顯示啟動畫面圖示尺寸。

啟動畫面動畫和啟動順序

額外延遲時間通常與在冷啟動時啟動應用程式有關。在啟動畫面加入動畫圖示不僅美觀,還能提供更優質的體驗。使用者研究顯示,瀏覽動畫時,感知啟動時間較短。

啟動畫面動畫內嵌於啟動序列元件中,如圖 4 所示。

以 12 個連續頁框顯示啟動順序的圖片。從輕觸啟動器圖示開始,並在放大時填滿畫面
圖 4. 啟動序列。
  1. 輸入動畫:加入系統檢視畫面到啟動畫面。它由系統控制,無法自訂。

  2. 啟動畫面 (在序列的「等待」部分顯示):您可以自訂啟動畫面,讓您提供自己的標誌動畫和品牌形象。必須符合本頁所述的要求才能正常運作。

  3. 離開動畫:這包含會隱藏啟動畫面的動畫。如要自訂,請使用 SplashScreenView 及其圖示。您可以執行任何動畫,並設定轉換、不透明度和顏色的設定。在此情況下,請在動畫完成後手動移除啟動畫面。

執行圖示動畫時,應用程式啟動可讓您選擇在應用程式較早準備就緒的情況下略過順序。應用程式會自動觸發 onResume() 或啟動畫面逾時,因此請確保動作可以正常略過。啟動畫面只有在應用程式從視覺角度保持穩定時,才能使用 onResume() 關閉,因此不需要額外的旋轉圖示。介紹不完整的介面可能會讓使用者感到困擾,並可能讓使用者產生無法預測或欠缺的印象。

啟動畫面動畫要求

啟動畫面必須符合以下規格:

  • 設定單一視窗不透明的背景顏色。SplashScreen Compat 程式庫支援白天和夜間模式。

  • 請確認動畫圖示符合下列規格:

    • 格式:圖示必須是 AnimatedVectorDrawable (AVD) XML。
    • 尺寸:AVD 圖示必須是自動調整圖示大小的四倍,如下所示:
      • 圖示區域必須是 432 dp,也就是未遮蓋的自動調整圖示中 108 dp 區域的四倍。
      • 圖片的前三分之二會顯示在啟動器圖示上,且大小必須為 288 dp,也就是構成自動調整圖示內部遮罩區域的 72 dp 四倍。
    • 時間長度:建議手機不要超過 1,000 毫秒。您可以使用延遲啟動,但不得超過 166 毫秒。如果應用程式啟動時間超過 1,000 毫秒,請考慮使用循環播放動畫。
  • 設定適當的關閉時間,關閉啟動畫面 (當應用程式繪製第一個影格時)。您可以按照「延長啟動畫面在螢幕上的停留時間」一節的說明,進一步自訂這項設定。

啟動畫面資源

圖 5.AVD 範例。

下載入門套件範例,示範如何建立動畫、設定動畫格式,以及將動畫匯出至 AVD。包含的內容如下:

  • 動畫的 Adobe After Effects 專案檔案。
  • 最終匯出的 AVD XML 檔案。
  • 動畫的 GIF 範例。

下載這些檔案即表示您同意《Google 服務條款》。

Google 隱私權政策》說明瞭這項服務處理資料的方式。

自訂應用程式中的啟動畫面

根據預設,如果 windowBackground 是單一顏色,則 SplashScreen 會使用主題的 windowBackground。如要自訂啟動畫面,請在應用程式佈景主題中加入屬性。

您可以執行下列任一操作,自訂應用程式的啟動畫面:

  • 設定主題屬性來變更外觀。

  • 延長在螢幕上的停留時間。

  • 自訂用於關閉啟動畫面的動畫。

開始使用

核心 SplashScreen 程式庫會將 Android 12 啟動畫面提供給所有搭載 API 23 的裝置。如要將以下內容加到專案,請在 build.gradle 檔案中新增以下程式碼片段:

Groovy

dependencies {
    implementation "androidx.core:core-splashscreen:1.0.0"
}

Kotlin

dependencies {
    implementation("androidx.core:core-splashscreen:1.0.0")
}

為啟動畫面設定一個主題以變更外觀

您可以在 Activity 主題中指定下列屬性,自訂應用程式的啟動畫面。如果您採用的舊版啟動畫面實作項目使用 android:windowBackground 等屬性,請考慮為 Android 12 以上版本提供替代資源檔案。

  1. 使用 windowSplashScreenBackground 將背景填滿特定單一顏色:

    <item name="android:windowSplashScreenBackground">@color/...</item>
    
  2. 使用 windowSplashScreenAnimatedIcon 取代起始視窗中央的圖示。

    如果應用程式僅指定 Android 12 (API 級別 32) 為目標,請按照下列步驟操作:

    如果物件是透過 AnimationDrawableAnimatedVectorDrawable 建立可繪製且可繪製的項目,請設定 windowSplashScreenAnimationDuration 以在顯示起始視窗時播放動畫。如果是 Android 13,則不必這麼做,因為時間是透過 AnimatedVectorDrawable 直接推斷。

    <item name="android:windowSplashScreenAnimatedIcon">@drawable/...</item>
    
  3. 使用 windowSplashScreenAnimationDuration 表示啟動畫面圖示動畫的時間長度。設定這項設定不會影響啟動畫面的實際顯示時間,但可以在使用 SplashScreenView.getIconAnimationDuration 自訂啟動畫面結束動畫時擷取。詳情請參閱下一節,瞭解如何延長啟動畫面在螢幕上的停留時間

    <item name="android:windowSplashScreenAnimationDuration">1000</item>
    
  4. 使用 windowSplashScreenIconBackgroundColor 設定啟動畫面圖示後方的背景。如果視窗背景與圖示之間的對比度不足,這項功能就能派上用場。

    <item name="android:windowSplashScreenIconBackgroundColor">@color/...</item>
    
  5. 您可以使用 windowSplashScreenBrandingImage 來設定要顯示在啟動畫面底部的圖片。不過,我們不建議使用品牌宣傳圖片。

    <item name="android:windowSplashScreenBrandingImage">@drawable/...</item>
    
  6. 您可以使用 windowSplashScreenBehavior,指定應用程式是否一律在 Android 13 以上版本的啟動畫面上顯示圖示。預設值為 0,如果啟動活動將 splashScreenStyle 設為 SPLASH_SCREEN_STYLE_ICON,啟動畫面就會顯示圖示;如果啟動活動未指定樣式,則會遵循系統行為。如果您不想顯示空白的啟動畫面,並一律希望顯示動畫圖示,請將此值設為 icon_preferred

    <item name="android:windowSplashScreenBehavior">icon_preferred</item>
    

延長啟動畫面在螢幕上的停留時間

應用程式會在首次繪製頁框時立即關閉啟動畫面。如果您需要載入少量資料 (例如以非同步方式載入本機磁碟的應用程式內設定),可以使用 ViewTreeObserver.OnPreDrawListener 暫停應用程式,以繪製其第一個影格。

如果您在繪圖前就啟動活動完成 (例如,未在 onResume 前設定內容檢視畫面並完成設定),就不需要預先繪製事件監聽器。

Kotlin

// Create a new event for the activity.
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Set the layout for the content view.
    setContentView(R.layout.main_activity)

    // Set up an OnPreDrawListener to the root view.
    val content: View = findViewById(android.R.id.content)
    content.viewTreeObserver.addOnPreDrawListener(
        object : ViewTreeObserver.OnPreDrawListener {
            override fun onPreDraw(): Boolean {
                // Check whether the initial data is ready.
                return if (viewModel.isReady) {
                    // The content is ready. Start drawing.
                    content.viewTreeObserver.removeOnPreDrawListener(this)
                    true
                } else {
                    // The content isn't ready. Suspend.
                    false
                }
            }
        }
    )
}

Java

// Create a new event for the activity.
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Set the layout for the content view.
    setContentView(R.layout.main_activity);

    // Set up an OnPreDrawListener to the root view.
    final View content = findViewById(android.R.id.content);
    content.getViewTreeObserver().addOnPreDrawListener(
            new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    // Check whether the initial data is ready.
                    if (mViewModel.isReady()) {
                        // The content is ready. Start drawing.
                        content.getViewTreeObserver().removeOnPreDrawListener(this);
                        return true;
                    } else {
                        // The content isn't ready. Suspend.
                        return false;
                    }
                }
            });
}

自訂用於關閉啟動畫面的動畫

您可以透過 Activity.getSplashScreen() 進一步自訂啟動畫面的動畫。

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // ...

    // Add a callback that's called when the splash screen is animating to the
    // app content.
    splashScreen.setOnExitAnimationListener { splashScreenView ->
        // Create your custom animation.
        val slideUp = ObjectAnimator.ofFloat(
            splashScreenView,
            View.TRANSLATION_Y,
            0f,
            -splashScreenView.height.toFloat()
        )
        slideUp.interpolator = AnticipateInterpolator()
        slideUp.duration = 200L

        // Call SplashScreenView.remove at the end of your custom animation.
        slideUp.doOnEnd { splashScreenView.remove() }

        // Run your animation.
        slideUp.start()
    }
}

Java

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

    // Add a callback that's called when the splash screen is animating to the
    // app content.
    getSplashScreen().setOnExitAnimationListener(splashScreenView -> {
        final ObjectAnimator slideUp = ObjectAnimator.ofFloat(
                splashScreenView,
                View.TRANSLATION_Y,
                0f,
                -splashScreenView.getHeight()
        );
        slideUp.setInterpolator(new AnticipateInterpolator());
        slideUp.setDuration(200L);

        // Call SplashScreenView.remove at the end of your custom animation.
        slideUp.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                splashScreenView.remove();
            }
        });

        // Run your animation.
        slideUp.start();
    });
}

開始此回呼後,啟動畫面的動畫向量可繪項目便會啟動。視應用程式啟動的時間長度而定,可繪項目可能會顯示在動畫的中間。使用 SplashScreenView.getIconAnimationStart 瞭解動畫開始的時間。可按照以下方法計算圖示動畫的剩餘時間:

Kotlin

// Get the duration of the animated vector drawable.
val animationDuration = splashScreenView.iconAnimationDuration
// Get the start time of the animation.
val animationStart = splashScreenView.iconAnimationStart
// Calculate the remaining duration of the animation.
val remainingDuration = if (animationDuration != null && animationStart != null) {
    (animationDuration - Duration.between(animationStart, Instant.now()))
        .toMillis()
        .coerceAtLeast(0L)
} else {
    0L
}

Java

// Get the duration of the animated vector drawable.
Duration animationDuration = splashScreenView.getIconAnimationDuration();
// Get the start time of the animation.
Instant animationStart = splashScreenView.getIconAnimationStart();
// Calculate the remaining duration of the animation.
long remainingDuration;
if (animationDuration != null && animationStart != null) {
    remainingDuration = animationDuration.minus(
            Duration.between(animationStart, Instant.now())
    ).toMillis();
    remainingDuration = Math.max(remainingDuration, 0L);
} else {
    remainingDuration = 0L;
}

其他資源