新增對預測返回動畫的支援

使用系統返回 API 時,您可以選擇接收應用程式內動畫,並支援自訂轉場效果。

影片:預測返回動畫

啟用這項功能後,應用程式會顯示返回首頁、跨活動和跨工作的動畫。

您也可以將 Material 元件的依附元件升級至 MDC Android 1.10.0 版,接收下列 Material 元件的動畫:

詳情請參閱 GitHub 上的 Material 元件開發人員指南

這部影片中的簡短範例是使用 Android「設定」應用程式,呈現跨活動和返回首頁的預測返回動畫。

  1. 在動畫中,使用者往回滑動,藉此返回上一個設定畫面。這是跨活動動畫的範例。
  2. 接著在上一個畫面中,使用者再次往回滑動,藉此預覽主畫面和桌布。這是返回首頁動畫的範例。
  3. 使用者持續向右滑動,出現視窗縮小為主畫面上圖示的動畫。
  4. 現在使用者已完全返回主畫面。

進一步瞭解如何新增預測返回手勢支援功能

新增自訂應用程式內轉場效果和動畫

您可以使用預測返回手勢,建立自訂應用程式內屬性動畫和轉場效果、自訂跨活動動畫,以及自訂跨片段動畫。

使用 Progress API 新增自訂轉場效果

在 AndroidX Activity 1.8.0-alpha01 以上版本中,您可以使用預測返回進度 API,為應用程式中的預測返回手勢開發自訂動畫。Progress API 有助於為檢視畫面製作動畫,但在片段之間建立動畫效果時有所限制。我們在 OnBackPressedCallback 中推出了 handleOnBackProgressedhandleOnBackCancelledhandleOnBackStarted 方法,可在使用者滑動返回時為物件建立動畫。除了系統提供的預設動畫,或是 Material 元件動畫之外,如果您需要自訂的內容,請使用這些方法。

我們預期大部分應用程式都會使用回溯相容的 AndroidX API,但 OnBackAnimationCallback 介面也提供類似的平台 API,方便您在 Android 14 開發人員預覽版 1 以上版本中進行測試。

搭配使用 AndroidX 轉場效果與 Progress API

在 Android 14 以上版本,Progress API 可搭配使用 AndroidX Transitions 1.5.0-alpha01 以上版本,建立預測返回轉場效果。

  1. 使用 TransitionManager#controlDelayedTransition (而非 beginDelayedTransition),在使用者滑動返回時顯示轉場效果。
  2. handleOnBackStarted 中建立轉場效果。
  3. currentFractionBackEvent.progress 建立關聯,公開使用者已滑動返回的距離,藉此在 handleOnBackProgressed 中的返回事件顯示轉場效果。
  4. 在使用者於 handleOnBackPressed 中採取返回手勢後完成轉場效果。
  5. 最後在 handleOnBackCancelled 內重設轉場效果的狀態。

以下影片、Kotlin 程式碼和 XML 示範如何使用 OnBackPressedCallback,在兩個方塊之間實作自訂轉場效果:

    class MyFragment : Fragment() {

    val transitionSet = TransitionSet().apply {
        addTransition(Fade(Fade.MODE_OUT))
        addTransition(ChangeBounds())
        addTransition(Fade(Fade.MODE_IN))
    }
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val callback = object : OnBackPressedCallback(enabled = false) {

            var controller: TransitionSeekController? = null

            @RequiresApi(34)
            override fun handleOnBackStarted(backEvent: BackEvent) {
                // Create the transition
                controller = TransitionManager.controlDelayedTransition(
                    binding.card,
                    transitionSet
                )
                changeTextVisibility(ShowText.SHORT)
            }

            @RequiresApi(34)
            override fun handleOnBackProgressed(backEvent: BackEvent) {
                // Play the transition as the user swipes back
                if (controller?.isReady == true) {
                    controller?.currentFraction = backEvent.progress
                }
            }

            override fun handleOnBackPressed() {
                // Finish playing the transition when the user commits back
                controller?.animateToEnd()
                this.isEnabled = false
            }

            @RequiresApi(34)
            override fun handleOnBackCancelled() {
                // If the user cancels the back gesture, reset the state
                transition(ShowText.LONG)
            }
        }

        binding.shortText.setOnClickListener {
            transition(ShowText.LONG)
            callback.isEnabled = true
        }

        this.requireActivity().onBackPressedDispatcher.addCallback(callback)
    }

    private fun transition(showText: ShowText) {
        TransitionManager.beginDelayedTransition(
            binding.card,
            transitionSet
        )
        changeTextVisibility(showText)
    }

    enum class ShowText { SHORT, LONG }
    private fun changeTextVisibility(showText: ShowText) {
        when (showText) {
            ShowText.SHORT -> {
                binding.shortText.isVisible = true
                binding.longText.isVisible = false
            }
            ShowText.LONG -> {
                binding.shortText.isVisible = false
                binding.longText.isVisible = true
            }
        }
    }
}
  
<?xml version="1.0" encoding="utf-8"?>
...
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/card"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ...>

        <TextView
            android:id="@+id/short_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            ... />

        <TextView
            android:id="@+id/long_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"
            .../>

    </androidx.constraintlayout.widget.ConstraintLayout>

使用預測返回轉場效果時,請注意下列事項:

  • 使用 isSeekingSupported,檢查轉場效果是否支援預測返回手勢。
  • 覆寫 isSeekingSupported,針對自訂轉場效果傳回 true。
  • 為每個動畫建立一個控制器。
  • AndroidX 轉換支援預測返回轉場效果,但架構轉換不支援。建議您從架構轉換遷移。
  • 預測返回轉場效果適用於搭載 Android 14 以上版本的裝置,且無法回溯相容。
  • 系統也支援使用 XML 場景建立的轉場效果。在 handleOnBackStarted 中,請將 TransitionSeekController 設為 TransitionManager.createSeekController 的結果,而非 controlDelayedTransition 的結果。

在 Android 14 以上版本新增自訂活動轉場效果

如要在 Android 14 以上版本中,確保自訂活動轉場效果可支援預測返回手勢,您可以使用 overrideActivityTransition,而不使用 overridePendingTransition。這表示使用者滑動返回時,系統會播放轉場效果動畫。

以下舉例說明這項機制的運作方式。假設在返回堆疊中,活動 B 位於活動 A 上方。您會採取下列做法處理自訂活動動畫:

  • 在活動 B 的 onCreate 方法中,呼叫開始或結束的轉場效果。
  • 在使用者前往活動 B 時,使用 OVERRIDE_TRANSITION_OPEN。在使用者滑動返回活動 A 時,則使用 OVERRIDE_TRANSITION_CLOSE
  • 如果指定 OVERRIDE_TRANSITION_CLOSEenterAnim 是活動 A 的進入動畫,exitAnim 則是活動 B 的結束動畫。

新支援:片段的預測返回功能

使用片段實作預測返回手勢時,有兩種方法。

使用現有 API

建議您使用現有的 API。這些 API 可讓您從螢幕邊緣滑動,利用手勢操控動畫器或 Androidx 轉場效果。不論手勢是否超過門檻,就能判斷手勢是否完成,並返回上一個片段;如果手勢取消,則動作取消,您會留在目前的片段。詳情請參閱「使用動畫瀏覽各個片段」。

以下是幾點注意事項:

  • 匯入 Transition 1.5.0 以上版本和 Fragment 1.7.0 以上版本。「Fragment」中大部分的預測返回手勢支援功能,都必須仰賴「Transition」的尋找動畫功能,而只有 Transition 1.5.0 以上版本才提供這項功能。
  • 使用 Fragment 搭配 FragmentManagerNavigation 元件 來處理返回堆疊。如果您自行管理返回堆疊,系統將不支援預測返回手勢。
  • 部分程式庫提供預測返回手勢支援功能,請參閱說明文件瞭解詳情。
  • 支援 Animator 類別和 AndroidX Transition 程式庫。
  • 不支援 Animation 類別和架構 Transition 程式庫。
  • 預測動畫僅適用於搭載 Android 14 以上版本的裝置。

請在下列情況使用預測返回跨片段:

1.12.02-alpha02 起,部分質感動態效果支援預測返回手勢,包括 MaterialFadeThroughMaterialSharedAxisMaterialFade。請注意,MaterialContainerTransform 不支援預測返回功能。

使用回呼

您可以使用回呼建立跨片段轉換,但是在使用回呼時有已知的限制,亦即使用者在滑動返回時看不到先前的片段。如要建立與預測返回設計指南對應的跨片段共用元素轉換,請執行下列步驟:

建立 OnBackPressedCallback。在 handleOnBackProgressed 中,縮放及移動片段。然後從返回堆疊中彈出。接下來,在回呼之外使用 setSharedElementReturnTransition 執行共用元素轉換。

詳情請參閱 GitHub 上的程式碼範例

相關規定

請參閱下表,瞭解開發人員選項、targetSdkVersioncompileSdkVersion、裝置版本、依附元件、資訊清單旗標和片段旗標控管的項目。第一個表格列出程式碼需求條件。

類別 動畫 compileSdk targetSdk android:enableOnBackInvokedCallback 依附元件
系統動畫 返回首頁 33 不限 TRUE 不通知
跨活動 34 不限 TRUE 不通知
跨工作 34 不限 TRUE 不通知
平台 自訂跨活動 34 不限 TRUE 不通知
Progress API 平台 34 不限 TRUE 不通知
Material Design 元件 底部功能表 34 不限 TRUE Material 元件 1.10.0
側邊功能表 34 不限 TRUE Material 元件 1.10.0
導覽匣 34 不限 TRUE Material 元件 1.10.0
搜尋 34 不限 TRUE Material 元件 1.10.0
Jetpack 動畫 自訂 AndroidX 跨片段 34 不限 TRUE AndroidX 片段 1.7
自訂 AndroidX 轉場效果 34 不限 TRUE AndroidX 轉場效果 1.5
Progress API Jetpack 34 不限 TRUE AndroidX 活動 1.8

如要瞭解允許使用者查看動畫的需求條件,請參閱下表。

類別 動畫 開發人員選項已啟用 裝置版本
系統動畫 返回首頁 TRUE 33
跨活動 TRUE 34
跨工作 TRUE 34
平台 自訂跨活動 TRUE 34
Progress API 平台 FALSE 34
Material Design 元件 底部功能表 FALSE 34
側邊功能表 FALSE 34
導覽匣 FALSE 34
搜尋 FALSE 34
Jetpack 動畫 自訂 AndroidX 跨片段 FALSE 34
自訂 AndroidX 轉場效果 FALSE 34
Progress API Jetpack FALSE 34

其他資源