返回导航是用户在之前访问过的屏幕历史记录中向后移动的方式。所有 Android 设备都为此类导航提供了一个返回按钮,因此请勿在应用的 UI 中添加返回按钮。根据用户的 Android 设备,此按钮可能是物理按钮或软件按钮。
当用户在您的应用中导航时,Android 会维护一个返回栈。这使得 Android 能够在按下返回按钮时正确导航到以前的目的地。但是,在某些情况下,您的应用可能需要实现自己的返回行为以提供最佳的用户体验。
例如,当使用WebView
时,您可能希望覆盖默认的返回按钮行为,以允许用户在 Web 浏览历史记录中向后导航,而不是应用中的先前屏幕。
Android 13 及更高版本包含 Android 设备的预测返回手势。要了解有关此功能的更多信息,请查看添加对预测返回手势的支持。
实现自定义返回导航
ComponentActivity
是 FragmentActivity
和 AppCompatActivity
的基类,它允许您通过使用其 OnBackPressedDispatcher
来控制返回按钮的行为,您可以通过调用 getOnBackPressedDispatcher()
来检索它。
该 OnBackPressedDispatcher
控制返回按钮事件如何分派到一个或多个 OnBackPressedCallback
对象。 OnBackPressedCallback
的构造函数采用一个布尔值作为初始启用状态。当回调启用时,即 isEnabled()
返回 true
,调度程序会调用回调的 handleOnBackPressed()
来处理返回按钮事件。您可以通过调用 setEnabled()
来更改启用状态。
回调是使用 addCallback
方法添加的。我们建议使用 addCallback()
方法,该方法采用 LifecycleOwner
。这确保 OnBackPressedCallback
仅在 LifecycleOwner
为 Lifecycle.State.STARTED
时添加。活动还在其关联的 LifecycleOwner
被销毁时删除已注册的回调,这可以防止内存泄漏,并使 LifecycleOwner
适用于片段或比活动生命周期更短的其他生命周期所有者。
这是一个回调实现示例
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
。
回调遵循责任链模式。链中的每个回调仅在前面的回调未启用时才被调用。这意味着,在前面的示例中,仅当回调 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
。