返回导航是用户在之前访问过的屏幕历史记录中向后移动的方式。所有 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
。这可确保仅当 LifecycleOwner
处于 Lifecycle.State.STARTED
状态时才添加 OnBackPressedCallback
。活动还会在其关联的 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
。但是,如果您无法进行此更改,则以下规则适用
- 通过
addCallback
注册的所有回调函数,都会在您调用super.onBackPressed()
时被评估。 - 在 Android 12(API 级别 32)及更低版本中,
onBackPressed
始终会被调用,无论是否注册了任何OnBackPressedCallback
实例。