提供自訂的返回瀏覽功能

返回瀏覽是指使用者如何依據之前造訪的螢幕歷史記錄往回瀏覽。所有 Android 裝置都會針對這類瀏覽提供返回按鈕,所以在應用程式的使用者介面上不應加上返回按鈕。視使用者的 Android 裝置而定,此按鈕有可能是實體按鈕也可能是軟體按鈕。

當使用者瀏覽應用程式時,Android 系統會保留目的地的返回堆疊。這通常可讓 Android 在使用者按下返回按鈕時正確瀏覽至之前的目的地。不過有時候應用程式可能需要實作自己的返回行為,以提供最佳的使用者體驗。舉例來說,使用 WebView 時,您可能會想要覆寫預設的返回按鈕行為,讓使用者可以返回其以往的網頁瀏覽記錄,而不是之前的應用程式畫面。

導入自訂返回瀏覽功能

FragmentActivityAppCompatActivity 的基本類別 ComponentActivity 可讓您透過 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