返回导航是指用户通过界面访问记录实现返回操作的方式。所有 Android 设备都为此类导航提供了返回按钮,因此请不要向应用的界面添加返回按钮。此按钮可以是物理按钮,也可以是软件按钮,具体取决于用户的 Android 设备。
用户在您的应用中导航时,Android 会维护目的地的返回堆栈。这样,当用户按返回按钮时,Android 便可以正确地导航到之前的目的地。不过,在少数情况下,您的应用可能需要实现自己的“返回”行为,以提供最佳用户体验。
例如,使用 WebView
时,您可能需要替换默认的返回按钮行为,以便用户通过其网页浏览记录(而不是应用中之前访问过的屏幕)返回。
Android 13 及更高版本包含适用于 Android 设备的预测性返回手势。如需详细了解此功能,请参阅添加对预测性返回手势的支持。
实现自定义返回导航
ComponentActivity
是 FragmentActivity
和 AppCompatActivity
的基类,可让您使用其 OnBackPressedDispatcher
来控制返回按钮的行为,该按钮可通过调用 getOnBackPressedDispatcher()
进行检索。
OnBackPressedDispatcher
控制将返回按钮事件分派给一个或多个 OnBackPressedCallback
对象的方式。OnBackPressedCallback
的构造函数利用布尔值指示初始启用状态。回调处于启用状态(即 isEnabled()
返回 true
)后,调度程序会调用回调的 handleOnBackPressed()
来处理返回按钮事件。您可以通过调用 setEnabled()
更改启用状态。
使用 addCallback
方法添加回调。我们建议您使用 addCallback()
方法,该方法接受 LifecycleOwner
。这可以确保仅在 LifecycleOwner
为 Lifecycle.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()
提供多个回调。当您这样做时,回调的调用顺序与您添加回调的顺序相反,即最后添加的回调是第一个有机会处理返回按钮事件的回调。例如,如果您添加三个名为 one
、two
和 three
的回调,则这些回调将按 three
、two
、one
的顺序调用。
回调遵循责任链模式。责任链中的每个回调仅在前面的回调处于未启用状态时调用。这意味着,在上述示例中,回调 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
的任何已注册实例。