提供自定义返回导航

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

当用户在您的应用程序中导航时,Android 会维护一个返回堆栈目标。这通常允许 Android 在按下返回按钮时正确导航到之前的目标。但是,在某些情况下,您的应用可能需要实现自己的返回行为,以便提供最佳的用户体验。例如,当使用WebView时,您可能希望覆盖默认的返回按钮行为,以允许用户在 Web 浏览历史记录中向后导航,而不是在您的应用中向后导航到之前的屏幕。

实现自定义返回导航

ComponentActivityFragmentActivityAppCompatActivity的基础类,允许您使用其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()提供多个回调。这样做时,回调的调用顺序与添加顺序相反——最后添加的回调首先有机会处理返回按钮事件。例如,如果您按顺序添加了三个名为onetwothree的回调,则它们的调用顺序将分别为threetwoone

回调遵循责任链模式。链中的每个回调只有在前面的回调未启用时才会被调用。这意味着在前面的示例中,只有当回调three未启用时,才会调用回调two。只有当回调two未启用时,才会调用回调one,依此类推。

请注意,当通过addCallback()添加时,回调只有在LifecycleOwner进入Lifecycle.State.STARTED状态后才会添加到责任链中。

强烈建议仅对OnBackPressedCallback的启用状态进行临时更改,因为它可以保持上述顺序,这在您在多个不同的嵌套生命周期所有者上注册回调时尤其重要。

但是,如果您想完全移除OnBackPressedCallback,则应调用remove()。然而,这通常没有必要,因为当其关联的LifecycleOwner销毁时,回调会自动移除。

Activity onBackPressed()

如果您正在使用onBackPressed()来处理后退按钮事件,我们建议改用OnBackPressedCallback。但是,如果您无法进行此更改,则适用以下规则:

  • 通过addCallback注册的所有回调都会在您调用super.onBackPressed()时进行评估。
  • 在 Android 12(API 级别 32)及更低版本中,无论已注册的OnBackPressedCallback实例有多少,都会始终调用onBackPressed