提供自定义返回导航

返回导航是指用户通过界面访问记录实现返回操作的方式。所有 Android 设备都为此类导航提供了返回按钮,因此请不要向应用的界面添加返回按钮。此按钮可以是物理按钮,也可以是软件按钮,具体取决于用户的 Android 设备。

用户在您的应用中导航时,Android 会维护目的地的返回堆栈。这样,当用户按返回按钮时,Android 便可以正确地导航到之前的目的地。不过,在少数情况下,您的应用可能需要实现自己的“返回”行为,以提供最佳用户体验。

例如,使用 WebView 时,您可能需要替换默认的返回按钮行为,以便用户通过其网页浏览记录(而不是应用中之前访问过的屏幕)返回。

Android 13 及更高版本包含适用于 Android 设备的预测性返回手势。如需详细了解此功能,请参阅添加对预测性返回手势的支持

实现自定义返回导航

ComponentActivityFragmentActivityAppCompatActivity 的基类,可让您使用其 OnBackPressedDispatcher 来控制返回按钮的行为,该按钮可通过调用 getOnBackPressedDispatcher() 进行检索。

OnBackPressedDispatcher 控制将返回按钮事件分派给一个或多个 OnBackPressedCallback 对象的方式。OnBackPressedCallback 的构造函数利用布尔值指示初始启用状态。回调处于启用状态(即 isEnabled() 返回 true)后,调度程序会调用回调的 handleOnBackPressed() 来处理返回按钮事件。您可以通过调用 setEnabled() 更改启用状态。

使用 addCallback 方法添加回调。我们建议您使用 addCallback() 方法,该方法接受 LifecycleOwner。这可以确保仅在 LifecycleOwnerLifecycle.State.STARTED 时添加 OnBackPressedCallback。此外,与注册的回调相关联的 LifecycleOwner 被销毁时,activity 还会移除注册的回调。这不仅可以防止内存泄漏,还可以使 LifecycleOwner 适用于生命周期短于该 activity 的 fragment 或其他生命周期所有者。

以下是一个回调实现示例:

Kotlin

class MyFragment : Fragment() {

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

        // This callback is only 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 is only 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 的顺序调用。

回调遵循责任链模式。责任链中的每个回调仅在前面的回调处于未启用状态时调用。这意味着,在上述示例中,回调 two 仅在未启用回调 three 时才会调用,回调 one 仅在未启用回调 two 时才会调用。

请注意,使用 addCallback() 添加回调后,在 LifecycleOwner 进入 Lifecycle.State.STARTED 状态之前,回调不会添加到责任链中。

我们建议您更改 OnBackPressedCallback 上的启用状态以进行临时更改,因为这样做可保持上述顺序。如果您在多个嵌套生命周期所有者上注册了回调,这一点尤为重要。

如果您想完全移除 OnBackPressedCallback,可以调用 remove()。这通常没有必要,因为回调会在与其关联的 LifecycleOwner销毁时自动移除。

activity onBackPressed()

如果您使用 onBackPressed() 处理返回按钮事件,我们建议您改用 OnBackPressedCallback。但是,如果您无法进行此项更改,请遵循以下规则:

  • 当您调用 super.onBackPressed() 时,系统对通过 addCallback 注册的所有回调进行评估。
  • 在 Android 12(API 级别 32)及更低版本中,始终调用 onBackPressed,而不考虑 OnBackPressedCallback 的任何已注册实例。