提供自訂的返回導覽功能

使用者可透過「返回瀏覽」功能返回先前瀏覽過的畫面。大多數 Android 裝置都有返回按鈕,包括實體按鈕、軟體按鈕或手勢操作。通常您不應在應用程式中新增返回按鈕。不過,相容模式下的 Android Automotive OS (AAOS) 裝置會使用系統返回按鈕。這會處理導覽作業,因此您不必自行新增。詳情請參閱「AAOS 相容模式」。

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

在 Compose 中實作自訂返回導覽功能

在 Jetpack Compose 中,您可以使用 BackHandler 可組合函式處理自訂返回導覽。

使用 Navigation Compose 時,您通常會使用 NavController.navigateUp() 或 NavController.popBackStack() 導覽至返回堆疊中的上一個畫面。不過,如果想在使用者按下系統返回鍵或使用返回手勢時實作自訂行為,BackHandler 就很有用。舉例來說,如果您在應用程式中顯示 WebView,可能會想允許使用者在按下系統返回鍵時,返回瀏覽記錄。

如果可組合項樹狀結構的不同層級有多個已啟用的 BackHandler 可組合項,只有最內層的可組合項會攔截返回事件。

使用 Views 實作自訂返回導覽功能

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

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

可透過 addCallback 方法新增回呼。請使用 addCallback() 方法,該方法會採用 LifecycleOwner。這樣一來,只有在 LifecycleOwner 為 Lifecycle.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() 提供多個回呼。進行這項操作時,系統叫用回呼的順序與新增時相反,因此最後新增的回呼會第一個處理返回按鈕事件。舉例來說,如果您依序新增 one、two 和 three 三個回呼,就會分別按照 three、two 和 one 的順序叫用。

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

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

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

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