用户通过 返回导航 在屏幕之间向后导航。大多数 Android 设备都配有返回按钮(物理按钮、软件按钮或基于手势的按钮)。通常,您不应在应用中添加返回按钮。但是,兼容模式下的 Android Automotive OS (AAOS) 设备使用系统返回按钮。此按钮可处理导航,因此您无需添加自己的返回按钮。如需了解详情,请参阅 AAOS 兼容模式。
用户在您的应用中导航时,Android 会维护一个目的地的返回堆栈。这通常允许 Android 在按下“返回”按钮时正确导航到先前的目的地。但是,在某些情况下,您的应用可能需要实现自己的返回行为,以提供最佳用户体验。例如,在使用 WebView
时,您可能希望替换默认的“返回”按钮行为,以允许用户返回其网页浏览历史记录,而不是返回应用中的先前屏幕。
实现自定义返回导航
ComponentActivity
是 FragmentActivity
和 AppCompatActivity
的基类,它允许您通过使用其 OnBackPressedDispatcher
来控制“返回”按钮的行为,您可以通过调用 getOnBackPressedDispatcher()
来检索它。
OnBackPressedDispatcher
控制“返回”按钮事件如何分派到一个或多个 OnBackPressedCallback
对象。OnBackPressedCallback
的构造函数接受一个布尔值,用于设置初始启用状态。只有当回调处于启用状态(即 isEnabled()
返回 true
)时,调度程序才会调用回调的 handleOnBackPressed()
来处理“返回”按钮事件。您可以通过调用 setEnabled()
来更改启用状态。
回调通过 addCallback
方法添加。强烈建议使用接受 LifecycleOwner
的 addCallback()
方法。这可确保只有当 LifecycleOwner
处于 Lifecycle.State.STARTED
状态时,才添加 OnBackPressedCallback
。当其关联的 LifecycleOwner
被销毁时,Activity 还会移除已注册的回调,这可以防止内存泄漏,并使其适用于 Fragment 或其他生命周期短于 Activity 的生命周期所有者。
以下是一个回调实现示例
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
被销毁时会自动移除。
Activity onBackPressed()
如果您正在使用 onBackPressed()
处理“返回”按钮事件,我们建议改用 OnBackPressedCallback
。但是,如果您无法进行此更改,则适用以下规则
- 当您调用
super.onBackPressed()
时,所有通过addCallback
注册的回调都会被评估。 - 在 Android 12(API 级别 32)及更低版本中,无论是否存在任何
OnBackPressedCallback
的注册实例,onBackPressed
都会始终被调用。