新增對預測返回手勢的支援

圖 1 模擬預測返回手勢在手機上的外觀和風格

預測返回是一種手勢導覽功能,可讓使用者預覽返回滑動手勢的結果。

舉例來說,使用返回手勢時,您可以看到應用程式後方主畫面的動畫預覽,如圖 1 中的模擬操作情形所示。

自 Android 15 起,預測返回動畫的開發人員選項已不再提供。對於已選擇全面啟用預測返回手勢的應用程式 (或在活動層級啟用),現在會顯示返回首頁、跨工作和跨活動等系統動畫。

您可以測試這個返回首頁動畫 (詳情請參閱本頁後續部分)。

如要取得預測返回手勢支援功能,您必須更新應用程式,使用具有回溯相容性的 OnBackPressedCallback AppCompat 1.6.0-alpha05 (AndroidX) 以上版本 API,或新的 OnBackInvokedCallback 平台 API。大多數應用程式都會使用具有回溯相容性的 AndroidX API。

這項更新提供遷移路徑,可正確攔截返回瀏覽,包括在 KeyEvent.KEYCODE_BACK 和任何使用 onBackPressed 方法的類別 (例如 ActivityDialog) 中,將返回攔截替換為新的系統 Back API。

程式碼研究室和 Google I/O 大會影片

除了使用本頁的說明文件,您還可以試用我們的程式碼研究室。它提供使用 AndroidX 活動 API 處理預測返回手勢的 WebView 常見用途實作。

您也可以觀看 Google I/O 大會影片,其中涵蓋實作 AndroidX 和平台 API 的更多範例。

更新使用預設返回瀏覽功能的應用程式

如果應用程式未實作任何自訂返回行為 (也就是將返回程序交由系統處理),更新應用程式就能直接支援這項功能。請按照本指南的說明選擇啟用這項功能

如果您的應用程式使用 Fragment 或 Navigation 元件,也請升級至 AndroidX Activity 1.6.0-alpha05 以上版本。

更新使用自訂返回瀏覽功能的應用程式

如果應用程式有實作自訂返回行為,則視其是否使用 AndroidX 以及處理返回瀏覽的方式而定,遷移路徑各有不同。

應用程式使用 AndroidX 應用程式處理返回瀏覽的方式 建議的遷移路徑 (本頁上的連結)
AndroidX API 遷移現有的 AndroidX 返回實作
不支援的平台 API 將含有不支援的返回瀏覽 API 的 AndroidX 應用程式遷移至 AndroidX API
不支援的平台 API,可遷移 將使用不支援的返回瀏覽 API 的應用程式遷移至平台 API
不支援的平台 API,但無法遷移 延遲啟用,直到返回瀏覽成為必要功能為止

遷移 AndroidX 返回瀏覽實作

這是最常見的用途,也是最建議的做法。這種做法適用於使用 OnBackPressedDispatcher 實作自訂手勢操作處理的全新或現有應用程式,詳情請參閱「提供自訂返回瀏覽功能」一文。

如果您的應用程式符合此類別,請按照下列步驟操作,讓應用程式支援預測返回手勢:

  1. 為確保已使用 OnBackPressedDispatcher API 的 API (例如 Fragments 和 Navigation 元件) 可與預測返回手勢完美搭配運作,請升級至 AndroidX Activity 1.6.0-alpha05

    // In your build.gradle file:
    dependencies {
    
    // Add this in addition to your other dependencies
    implementation "androidx.activity:activity:1.6.0-alpha05"
    
  2. 按照本頁所述選擇啟用預測返回手勢

將含有不支援的返回瀏覽 API 的 AndroidX 應用程式遷移至 AndroidX API

如果應用程式使用 AndroidX 程式庫,但實作或參照不支援的返回瀏覽 API,您必須改用 AndroidX API 來支援新行為。

如何將不支援的 API 遷移至 AndroidX API:

  1. 實作 OnBackPressedCallback 即可將系統 Back 處理邏輯遷移至 AndroidX 的 OnBackPressedDispatcher。如需詳細指南,請參閱「提供自訂返回瀏覽功能」。

  2. 在準備好停止攔截返回手勢時,停用 OnBackPressedCallback

  3. 停止透過 OnBackPressedKeyEvent.KEYCODE_BACK 攔截返回事件。

  4. 請務必升級至 AndroidX Activity 1.6.0-alpha05

    // In your build.gradle file:
    dependencies {
    
    // Add this in addition to your other dependencies
    implementation "androidx.activity:activity:1.6.0-alpha05"
    
  5. 應用程式順利遷移後,請按照本頁所述選擇啟用預測返回手勢,查看「返回主畫面」系統動畫。

將使用不支援的返回瀏覽 API 的應用程式遷移至平台 API

如果應用程式無法使用 AndroidX 程式庫,而是改用不支援的 API 實作或參照自訂 Back 瀏覽,就必須遷移至 OnBackInvokedCallback 平台 API。

如要將不支援的 API 遷移至平台 API,請完成下列步驟:

  1. 在搭載 Android 13 以上版本的裝置上使用新的 OnBackInvokedCallback API。如果是搭載 Android 12 以下版本的裝置,則使用不支援的 API。

  2. 透過 onBackInvokedDispatcher,在 OnBackInvokedCallback 中註冊自訂返回邏輯。這樣可以避免結束目前的活動,讓回呼有機會在使用者完成系統 Back 瀏覽後回應 Back 動作。

  3. 在準備好停止攔截返回手勢後,取消註冊 OnBackInvokedCallback。否則,使用者在使用系統 Back 瀏覽時,可能會遇到不想要的行為,例如無法在檢視畫面之間「順暢轉換」,因而必須強制退出應用程式。

    以下範例說明如何從 onBackPressed 中遷出邏輯:

    Kotlin

    @Override
    fun onCreate() {
        if (BuildCompat.isAtLeastT()) {
            onBackInvokedDispatcher.registerOnBackInvokedCallback(
                OnBackInvokedDispatcher.PRIORITY_DEFAULT
            ) {
                /**
                 * onBackPressed logic goes here. For instance:
                 * Prevents closing the app to go home screen when in the
                 * middle of entering data to a form
                 * or from accidentally leaving a fragment with a WebView in it
                 *
                 * Unregistering the callback to stop intercepting the back gesture:
                 * When the user transitions to the topmost screen (activity, fragment)
                 * in the BackStack, unregister the callback by using
                 * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback
                 * (https://developer.android.com/reference/kotlin/android/window/OnBackInvokedDispatcher#unregisteronbackinvokedcallback)
                 */
            }
        }
    }

    Java

    @Override
    void onCreate() {
      if (BuildCompat.isAtLeastT()) {
        getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT,
            () -> {
              /**
               * onBackPressed logic goes here - For instance:
               * Prevents closing the app to go home screen when in the
               * middle of entering data to a form
               * or from accidentally leaving a fragment with a WebView in it
               *
               * Unregistering the callback to stop intercepting the back gesture:
               * When the user transitions to the topmost screen (activity, fragment)
               * in the BackStack, unregister the callback by using
               * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback
               * (https://developer.android.com/reference/kotlin/android/view/OnBackInvokedDispatcher#unregisteronbackinvokedcallback)
               */
            }
        );
      }
    }
  4. 針對 Android 13 以上版本,停止透過 OnBackPressedKeyEvent.KEYCODE_BACK 攔截返回事件。

  5. 應用程式順利遷移後,請按照本頁所述選擇啟用預測返回手勢,讓 OnBackInvokedCallback 生效。

您可以使用 PRIORITY_DEFAULTPRIORITY_OVERLAY 註冊 OnBackInvokedCallback,這在類似的 AndroidX OnBackPressedCallback 中無法使用。在某些情況下,使用 PRIORITY_OVERLAY 註冊回呼非常實用。

這項做法適用於從 onKeyPreIme() 遷移,且回呼需要接收返回手勢,而非開啟的 IME。IME 開啟時,會使用 PRIORITY_DEFAULT 註冊回呼,因此使用 PRIORITY_OVERLAY 註冊回呼,可確保 OnBackInvokedDispatcher 將返回手勢分派給您的回呼,而非開啟的 IME。

選擇啟用預測返回手勢

當您根據自身情況決定應用程式的更新方式後,即可選擇讓應用程式支援預測返回手勢。

如要選擇啟用這項功能,請在 AndroidManifest.xml<application> 標記中將 android:enableOnBackInvokedCallback 旗標設為 true

<application
    ...
    android:enableOnBackInvokedCallback="true"
    ... >
...
</application>

如未提供值,這個旗標會預設為 false,並執行下列動作:

  • 停用預測返回手勢系統動畫。
  • 忽略 OnBackInvokedCallback,但 OnBackPressedCallback 呼叫繼續運作。

在活動層級選擇啟用

自 Android 14 起,android:enableOnBackInvokedCallback 旗標可讓您在活動層級選擇啟用預測系統動畫。透過這個行為,您可以更輕鬆管理將大型多活動應用程式遷移至預測返回手勢的過程。在 Android 15 中,預測返回功能不再位於開發人員選項後方。應用程式可以選擇全面啟用預測返回功能,也可以在活動層級啟用。

以下程式碼示範如何使用 enableOnBackInvokedCallback 啟用 MainActivity 的「返回主畫面」系統動畫:

<manifest ...>
    <application . . .

        android:enableOnBackInvokedCallback="false">

        <activity
            android:name=".MainActivity"
            android:enableOnBackInvokedCallback="true"
            ...
        </activity>
        <activity
            android:name=".SecondActivity"
            android:enableOnBackInvokedCallback="false"
            ...
        </activity>
    </application>
</manifest>

在上述範例中,為 ".SecondActivity" 設定 android:enableOnBackInvokedCallback=true 會啟用跨活動系統動畫。

使用 android:enableOnBackInvokedCallback 旗標時,請注意下列事項:

  • 設定 android:enableOnBackInvokedCallback=false 會根據旗標的設定位置,在活動層級或應用程式層級關閉預測返回動畫,並指示系統忽略對 OnBackInvokedCallback 平台 API 的呼叫。不過,由於 OnBackPressedCallback 具有回溯相容性,且會呼叫 onBackPressed API (Android 13 以下版本不支援此 API),因此對 OnBackPressedCallback 的呼叫會繼續執行。
  • 在應用程式層級設定 enableOnBackInvokedCallback 旗標,會為應用程式中的所有活動建立預設值。您可以在活動層級設定旗標,覆寫每項活動的預設值,如上述程式碼範例所示。

回呼最佳做法

使用 BackHandler (適用於 Compose)、OnBackPressedCallbackOnBackInvokedCallback 等支援的系統返回回呼時,請參考以下最佳做法。

決定能啟用及停用每個回呼的 UI 狀態

UI 狀態是一種用來描述 UI 的屬性。建議您按照以下概略步驟操作。

  1. 決定能啟用及停用每個回呼的 UI 狀態。

  2. 使用可觀測的資料容器類型 (例如 StateFlow 或 Compose State) 定義狀態,並在狀態變更時啟用或停用回呼。

如果應用程式先前已將返回邏輯與條件陳述式建立關聯,這可能表示您是在返回事件發生後才做出回應。請避免在較新的回呼中使用這種模式。如果可以,請將回呼移至條件陳述式之外,並改將回呼與可觀測的資料容器類型建立關聯。

將系統返回回呼用於 UI 邏輯

UI 邏輯會決定 UI 顯示方式。請使用系統返回回呼執行 UI 邏輯,例如顯示彈出式視窗或執行動畫。

如果應用程式啟用系統返回回呼,預測動畫就不會執行,您也必須處理返回事件。請勿建立僅執行非 UI 邏輯的回呼。

舉例來說,如果攔截返回事件只是為了記錄資料,請改為在 Activity 或 Fragment 生命週期內記錄資料。

  • 若是活動對活動或片段對活動的情況,請在 onDestroy 中的 isFinishingtrue 時,於 Activity 生命週期內記錄資料。
  • 若是片段對片段的情況,請在 onDestroy 中的 isRemoving 於片段的檢視畫面生命週期內為 true 時記錄資料。或者,您也可以使用 FragmentManager.OnBackStackChangedListener 中的 onBackStackChangeStartedonBackStackChangeCommitted 方法進行記錄。

在 Compose 案例中,請在與 Compose 目的地相關聯的 ViewModel onCleared() 回呼中記錄資料。這是瞭解 Compose 目的地何時從返回堆疊彈出及銷毀的最佳信號。

建立單一責任回呼

您可以對調度工具新增多個回呼。回呼會新增至堆疊中,堆疊內最後新增的已啟用回呼會處理下一個返回手勢,而每個返回手勢都有一個回呼。

如果回呼只有單一責任,管理回呼的啟用狀態就會更容易。例如:

堆疊中回呼的順序。
圖 2. 回呼堆疊圖表。

圖 2 顯示如何在堆疊中使用多個回呼,每個回呼負責一項工作。只有在堆疊中上層的回呼已停用時,回呼才會執行。在這個範例中,如果使用者在表單中輸入資料,系統就會啟用「Are you sure...」回呼,否則則會停用。當使用者向後滑動退出表單時,回呼會開啟確認對話方塊。

其他回呼可能包含支援預測返回的 Material 元件、使用 Progress API 的 AndroidX 轉場,或其他自訂回呼。

如果上述回呼已停用,且此 FragmentManager 的返回堆疊並非空白,childFragmentManager 會附加至 Fragment 中,此時 childFragmentManager 的回呼就會執行。在本範例中,此內部回呼已停用。

同樣地,如果上述回呼已停用且堆疊非空,supportFragmentManager 的內部回呼也會執行。使用 FragmentManagerNavigationComponent 進行導覽時,這項行為會保持一致,因為 NavigationComponent 會依賴 FragmentManager。在這個範例中,如果使用者未在表單中輸入文字,導致「Are you sure...」回呼停用,系統就會執行這個回呼。

最後,super.onBackPressed() 是系統層級的回呼,如果上述回呼遭到停用,系統會再次執行 super.onBackPressed()。為了觸發系統動畫 (例如返回首頁、跨活動和跨工作),supportFragmentManager 的返回堆疊必須為空白,以便停用內部回呼。

測試預測返回手勢動畫

如果您仍使用 Android 13 或 Android 14,可以測試圖 1 中的返回主畫面動畫。

如要測試這個動畫,請完成下列步驟:

  1. 在裝置上,依序前往「設定」>「系統」>「開發人員選項」

  2. 選取「預測返回操作動畫」

  3. 啟動更新後的應用程式,然後使用返回手勢查看實際運作情形。