新增對內建和自訂預測返回動畫的支援

如果您已將應用程式遷移至新的系統返回 API,可以選擇啟用預測返回功能來自動接收應用程式內動畫,並支援自訂轉場效果。

新增對內建應用程式內動畫的支援

影片:預測返回動畫

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

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

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

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

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

進一步瞭解如何支援預測返回手勢

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

您可以使用 Progress API 和自訂跨活動動畫方法 overrideActivityTransition,建立自訂應用程式內屬性動畫和轉場效果。

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

在 AndroidX Activity 1.8.0-alpha01 以上版本中,您可以使用 Predictive Back 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 的結束動畫。