提供自定义返回导航

返回导航是用户在访问过的屏幕历史记录中向后移动的方式。所有 Android 设备都提供了用于此类型导航的返回按钮,因此请勿在您应用的 UI 中添加返回按钮。根据用户的 Android 设备,此按钮可能是物理按钮或软件按钮。

当用户在您的应用中导航时,Android 会维护一个目的地返回堆栈。当按下返回按钮时,这可以让 Android 正确地导航到之前的目的地。但是,在某些情况下,您的应用可能需要实现自己的返回行为,以提供最佳的用户体验。

例如,在使用 WebView 时,您可能希望覆盖默认的返回按钮行为,以让用户通过其网页浏览历史记录而非应用中的先前屏幕进行导航。

Android 13 及更高版本包含适用于 Android 设备的预测性返回手势。要了解有关此功能的更多信息,请参阅添加对预测性返回手势的支持

实现自定义返回导航

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

OnBackPressedDispatcher 控制返回按钮事件如何分派给一个或多个 OnBackPressedCallback 对象。OnBackPressedCallback 的构造函数接受一个布尔值作为初始启用状态。当回调被启用时(即 isEnabled() 返回 true),分派器会调用回调的 handleOnBackPressed() 来处理返回按钮事件。您可以通过调用 setEnabled() 来更改启用状态。

使用 addCallback 方法添加回调。我们建议使用 addCallback() 方法,该方法接受一个 LifecycleOwner。这可确保仅当 LifecycleOwner 处于 Lifecycle.State.STARTED 状态时才添加 OnBackPressedCallback。当与其关联的 LifecycleOwner 被销毁时,Activity 还会移除已注册的回调,这可以防止内存泄漏,并使 LifecycleOwner 适合在片段或其他生命周期比 Activity 短的生命周期所有者中使用。

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

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)及更低版本中,无论是否注册了 OnBackPressedCallback 的任何实例,始终会调用 onBackPressed