提供自訂的返回導覽功能

「返回導覽」指的是使用者依據先前造訪的畫面記錄往回導覽。所有 Android 裝置都有返回按鈕可執行這類導覽動作,因此不建議您在應用程式 UI 中加入返回按鈕。視使用者的 Android 裝置而定,此按鈕可能是實體按鈕或軟體按鈕。

使用者在應用程式導覽各頁面時,Android 會保留目的地的「返回堆疊」。一般來說,當使用者按下返回按鈕時,Android 會利用這項功能正確地前往先前的目的地。但在少數情況下,為了提供最佳使用者體驗,應用程式可能需要實作自己的返回行為。舉例來說,使用 WebView 時,您可能會想要覆寫預設的返回按鈕行為,讓使用者根據網頁瀏覽記錄進行返回,而不是之前的應用程式畫面。

實作自訂返回導覽功能

ComponentActivityFragmentActivityAppCompatActivity 的基礎類別,可讓您透過 OnBackPressedDispatcher 控制返回按鈕的行為,該項目可透過呼叫 getOnBackPressedDispatcher() 取得。

OnBackPressedDispatcher 可控管系統如何將返回按鈕事件分派到一或多個 OnBackPressedCallback 物件。OnBackPressedCallback 的建構函式會以布林值表示初始啟用狀態。只有在已啟用回呼的情況下 (即 isEnabled() 傳回 true),分派器才會呼叫回呼的 handleOnBackPressed() 來處理返回按鈕事件。呼叫 setEnabled() 即可改變啟用狀態。

可透過 addCallback 方法新增回呼。強烈建議選用會讀取 LifecycleOwneraddCallback() 方法。此方法可確保只有在 LifecycleOwnerLifecycle.State.STARTED 時,才會新增 OnBackPressedCallback。當相關 LifecycleOwner 遭到刪除時,活動也會移除已註冊的回呼,藉此防止記憶體流失,並讓回呼適合用於片段或其他生命週期擁有者 (生命週期比該活動短時)。

以下是回呼的實作範例:

Kotlin

class MyFragment : Fragment() {

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

        // This callback will only be called when MyFragment is at least Started.
        val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
            // Handle the back button event
        }

        // The callback can be enabled or disabled here or in the lambda
    }
    ...
}

Java

public class MyFragment extends Fragment {

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

        // This callback will only be called when MyFragment is at least Started.
        OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
            @Override
            public void handleOnBackPressed() {
                // Handle the back button event
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

        // The callback can be enabled or disabled here or in handleOnBackPressed()
    }
    ...
}

您可以透過 addCallback() 提供多個回呼。進行這項操作時,系統叫用回呼的順序與新增時相反,因此最後新增的回呼會第一個處理返回按鈕事件。舉例來說,如果您依序新增 onetwothree 三個回呼,就會分別按照 threetwoone 的順序叫用。

回呼會依循責任鏈模式。除非前一個回呼未啟用,系統才會叫用鏈結中的回呼。也就是說 上述範例,只有在回呼 three 時才會叫用 two 回呼 未啟用。只有在回呼 two 時才會叫用 one 回呼 以及未啟用,依此類推

請注意,透過 addCallback() 新增回呼時,只有當 LifecycleOwner 進入 Lifecycle.State.STARTED 狀態後,回呼才會新增至責任鏈。

針對臨時性的變更,強烈建議您變更 OnBackPressedCallback 上的已啟用狀態,因為這個做法會保持上述順序。如果回呼是由多個不同的巢狀生命週期擁有者註冊,就必須特別注意這一點。

不過,如要徹底移除 OnBackPressedCallback,應呼叫 remove()。但通常不需要這麼做,因為系統刪除與回呼相關聯的 LifecycleOwner 時,會自動移除回呼。

BackPressed() 活動

如果您使用 onBackPressed() 處理返回按鈕事件,建議改用 OnBackPressedCallback。不過若無法進行此項變更,則套用下列規則:

  • 所有透過 addCallback 註冊的回呼均會在您呼叫 super.onBackPressed() 時進行評估。
  • 在 Android 12 (API 級別 32) 以下版本中,無論 OnBackPressedCallback 的註冊例項為何,一律會呼叫 onBackPressed