
预测性返回是一项手势导航功能,可让用户预览向后滑动时即将前往的位置。
例如,使用返回手势可以在应用后面显示主屏幕的动画预览,如图 1 中的模型所示。
从 Android 15 开始,用于预测性返回动画的开发者选项不再可用。现在,如果应用已选择完全启用或在 activity 级别启用预测性返回手势,则会显示“返回主屏幕”、跨任务和跨 activity 等系统动画。
您可以测试这种返回主屏幕动画(如本页的下一部分所述)。
如需支持预测性返回手势,您需要使用向后兼容的 OnBackPressedCallback
AppCompat 1.6.0-alpha05 (AndroidX) 或更高版本的 API 或使用新的 OnBackInvokedCallback
平台 API 更新应用。大多数应用都使用向后兼容的 AndroidX API。
此更新提供了一种迁移路径,可正确拦截返回导航,包括在 KeyEvent.KEYCODE_BACK
和任何使用 onBackPressed
方法的类(例如 Activity
和 Dialog
)中,将返回拦截替换成新的系统 Back API。
Codelab 和 Google I/O 大会视频
除了参考本页的文档外,您还可以试用我们的 Codelab, 其中提供了使用 AndroidX Activity API 处理预测性返回手势的常见 WebView 用例实现。
您还可以观看我们的 Google I/O 视频,其中介绍了实现 AndroidX 和平台 API 的其他示例。
更新使用默认返回导航的应用
预测性返回功能默认处于启用状态。
如果您的应用使用 fragment 或 Navigation 组件,也请升级到 AndroidX Activity 1.6.0-alpha05 或更高版本。
更新使用自定义返回导航的应用
如果您的应用实现了自定义返回行为,则会有不同的迁移路径,具体取决于它是否使用了 AndroidX 以及它如何处理返回导航。
您的应用是否使用了 AndroidX | 您的应用会如何处理返回导航 | 推荐的迁移路径(此页面上的链接) |
是 | AndroidX APIs | 迁移现有的 AndroidX 返回实现 |
不受支持的平台 API | 将包含不受支持的返回导航 API 的 AndroidX 应用迁移至 AndroidX API | |
否 | 不受支持的平台 API,可以迁移 | 将使用不受支持的返回导航 API 的应用迁移至平台 API |
不受支持的平台 API,但无法迁移 | 如需暂时选择不使用,请在应用的 AndroidManifest.xml 文件的 <application> 或 <activity> 代码中将 android:enableOnBackInvokedCallback 属性设置为 false 。 |
迁移 AndroidX 返回导航实现
此用例最常见(也最推荐)。它适用于使用 OnBackPressedDispatcher
实现自定义手势导航处理功能的新应用或现有应用,如提供自定义返回导航中所述。
为了确保已在使用 OnBackPressedDispatcher
的 API(例如 fragment 和 Navigation 组件)能够与预测性返回手势完美配合,请升级到 AndroidX Activity 1.6.0-alpha05。
```xml
// In your build.gradle file:
dependencies {
// Add this in addition to your other dependencies
implementation "androidx.activity:activity:1.6.0-alpha05"
```
将包含不受支持的返回导航 API 的 AndroidX 应用迁移至 AndroidX API
如果您的应用使用 AndroidX 库,但会实现或引用不受支持的返回导航 API,则需要改用 AndroidX API 来支持新行为。
如需将不受支持的 API 迁移到 AndroidX API,请执行以下操作:
通过实现
OnBackPressedCallback
将系统返回导航处理逻辑迁移到 AndroidX 的OnBackPressedDispatcher
。如需获得详细指导,请参阅提供自定义返回导航。当已为停止拦截返回手势做好准备时,停用
OnBackPressedCallback
。停止通过
OnBackPressed
或KeyEvent.KEYCODE_BACK
拦截返回事件。请务必升级到 AndroidX Activity 1.6.0-alpha05。
// In your build.gradle file: dependencies { // Add this in addition to your other dependencies implementation "androidx.activity:activity:1.6.0-alpha05"
将使用不受支持的返回导航 API 的应用迁移至平台 API
如果您的应用无法使用 AndroidX 库,而是使用不受支持的 API 实现或引用自定义返回导航,您必须迁移到 OnBackInvokedCallback
平台 API。
完成以下步骤,将不受支持的 API 迁移到平台 API:
在搭载 Android 13 或更高版本的设备上使用新的
OnBackInvokedCallback
API,并在搭载 Android 12 或更低版本的设备上依赖不受支持的 API。在
OnBackInvokedCallback
中向onBackInvokedDispatcher
注册您的自定义返回逻辑。这样可防止结束当前的 activity,让回调有机会在用户完成系统返回导航后响应返回操作。当已为停止拦截返回手势做好准备时,取消注册
OnBackInvokedCallback
。否则,用户在使用系统返回导航时,可能会遇到不希望出现的行为,例如在视图之间“卡住”并被强制退出应用。以下示例展示了如何从
onBackPressed
迁移出逻辑:Kotlin
@Override fun onCreate() { if (BuildCompat.isAtLeastT()) { onBackInvokedDispatcher.registerOnBackInvokedCallback( OnBackInvokedDispatcher.PRIORITY_DEFAULT ) { /** * onBackPressed logic goes here. For instance: * Prevents closing the app to go home screen when in the * middle of entering data to a form * or from accidentally leaving a fragment with a WebView in it * * Unregistering the callback to stop intercepting the back gesture: * When the user transitions to the topmost screen (activity, fragment) * in the BackStack, unregister the callback by using * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback * (https://developer.android.com/reference/kotlin/android/window/OnBackInvokedDispatcher#unregisteronbackinvokedcallback) */ } } }
Java
@Override void onCreate() { if (BuildCompat.isAtLeastT()) { getOnBackInvokedDispatcher().registerOnBackInvokedCallback( OnBackInvokedDispatcher.PRIORITY_DEFAULT, () -> { /** * onBackPressed logic goes here - For instance: * Prevents closing the app to go home screen when in the * middle of entering data to a form * or from accidentally leaving a fragment with a WebView in it * * Unregistering the callback to stop intercepting the back gesture: * When the user transitions to the topmost screen (activity, fragment) * in the BackStack, unregister the callback by using * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback * (https://developer.android.com/reference/kotlin/android/view/OnBackInvokedDispatcher#unregisteronbackinvokedcallback) */ } ); } }
对于 Android 13 及更高版本,停止使用
OnBackPressed
或KeyEvent.KEYCODE_BACK
拦截返回事件。
您可以向 PRIORITY_DEFAULT
或 PRIORITY_OVERLAY
注册 OnBackInvokedCallback
,后者在类似的 AndroidX OnBackPressedCallback
中不可用。在某些情况下,向 PRIORITY_OVERLAY
注册回调会很有帮助。
当您从 onKeyPreIme()
迁移并且回调需要接收返回手势而不是打开的 IME 时,此注册回调方式适用。IME 在打开时会向 PRIORITY_DEFAULT
注册回调。请向 PRIORITY_OVERLAY
注册回调,以确保 OnBackInvokedDispatcher
将返回手势分派给回调而不是打开的 IME。
选择停用预测性返回
如需选择停用预测性返回手势,请在 AndroidManifest.xml
的 <application>
标记中将 android:enableOnBackInvokedCallback
标志设置为 false
。
<application
...
android:enableOnBackInvokedCallback="false"
... >
...
</application>
如果将此属性设置为 false,则会执行以下操作:
- 停用预测性返回手势系统动画。
- 忽略
OnBackInvokedCallback
,但OnBackPressedCallback
调用将继续有效。
在 activity 级别选择停用
您可以使用 android:enableOnBackInvokedCallback
标志在 activity 级别选择停用预测性系统动画。此行为有助于更轻松地管理将大型多 activity 应用迁移到预测性返回手势的过程。
以下代码展示了将 enableOnBackInvokedCallback
设置为从 MainActivity
启用“返回主屏幕”系统动画的示例:
<manifest ...>
<application . . .
android:enableOnBackInvokedCallback="false">
<activity
android:name=".MainActivity"
android:enableOnBackInvokedCallback="true"
...
</activity>
<activity
android:name=".SecondActivity"
android:enableOnBackInvokedCallback="false"
...
</activity>
</application>
</manifest>
在使用 android:enableOnBackInvokedCallback
标志时,请注意以下事项:
- 设置
android:enableOnBackInvokedCallback=false
会在 activity 级别或应用级别关闭预测性返回动画(具体取决于您在哪个级别设置了标记),并指示系统忽略对OnBackInvokedCallback
平台 API 的调用。不过,对OnBackPressedCallback
的调用会继续运行,因为OnBackPressedCallback
向后兼容,并会调用 Android 13 之前的版本不支持的onBackPressed
API。 - 在应用级别设置
enableOnBackInvokedCallback
标志会为应用中的所有 activity 建立默认值。您可以在 activity 级别设置标志来替换每个 activity 的默认值,如前面的代码示例所示。
回调最佳实践
使用 BackHandler
(适用于 Compose)、OnBackPressedCallback
或 OnBackInvokedCallback
等受支持的系统返回回调时,请遵循以下最佳实践。
确定用于启用和停用每个回调的界面状态
界面状态是描述界面的属性。我们建议您遵循以下简要步骤。
确定用于启用和停用每个回调的界面状态。
使用可观察数据容器类型(例如
StateFlow
或 Compose State)定义该状态,并在状态更改时启用或停用回调。
如果您的应用之前已将返回逻辑与条件语句相关联,这可能表示您是在返回事件发生后才做出回应。请避免使用这种模式,而改用较新的回调。 如果可能,请将回调移出条件语句,并改为将回调与可观察数据容器类型关联起来。
对界面逻辑使用系统返回回调
界面逻辑决定着如何显示界面。您可以使用系统返回回调运行界面逻辑,例如显示对话框或运行动画。
如果您的应用启用了 OnBackPressedCallback
或 OnBackInvokedCallback
并搭配 PRIORITY_DEFAULT
或 PRIORITY_OVERLAY
,则预测性返回动画不会运行,并且您必须处理返回事件。请勿创建这些回调来运行业务逻辑或进行日志记录。
如果您的应用必须在用户向后滑动时运行业务逻辑或记录日志,请使用以下方法:
- 在搭载 Android 16 及更高版本的设备上,将
OnBackInvokedCallback
与PRIORITY_SYSTEM_NAVIGATION_OBSERVER
搭配使用。这会创建一个不消耗返回事件的观察者回调。例如,您可以在用户从根 activity 向后滑动时(换句话说,在用户离开您的应用时)注册此回调。在这种情况下,您可以记录返回事件或运行其他业务逻辑,并且返回首页动画仍会播放。 - 在 activity 到 activity 或 fragment 到 activity 的情况下,如果
onDestroy
中的isFinishing
为true
,请在 activity 生命周期内进行记录。 - 在 fragment 到 fragment 的情况下,如果
onDestroy
中的isRemoving
为 true,请在 fragment 的视图生命周期中进行记录。或者,使用FragmentManager.OnBackStackChangedListener
中的onBackStackChangeStarted
或onBackStackChangeCommitted
方法进行记录。 - 对于 Compose 场景,请在与 Compose 目的地相关联的
ViewModel
的onCleared()
回调中记录日志。这是了解 Compose 目的地何时从返回堆栈中弹出并销毁的最佳信号。
创建单一责任回调
您可以向调度程序添加多个回调。这些回调将添加到堆栈中,其中最近添加的已启用回调会处理下一个返回手势,且每个返回手势对应一个回调。
如果回调具有单一职责,则更容易管理回调的启用状态。例如:

图 2 显示了堆栈中可以有多个回调,每个回调负责一项任务。只有当堆栈中位于其上方的回调处于停用状态时,回调才会运行。在此示例中,当用户在表单中输入数据时,系统会启用“您确定要...吗?”回调,否则会停用该回调。 当用户向后滑动以退出表单时,该回调会打开一个确认对话框。
另一个回调可以包含支持预测性返回的 Material 组件、使用 Progress API 的 AndroidX 转场效果或其他自定义回调。
如果上述回调被停用,且相应 FragmentManager
的返回堆栈不为空,则会运行 childFragmentManager
的回调,其中 childFragmentManager
附加在 Fragment 内。在此示例中,此内部回调处于停用状态。
同样,如果上述回调被停用,且 supportFragmentManager
的堆栈不为空,则 supportFragmentManager
的内部回调会运行。无论是使用 FragmentManager
还是 NavigationComponent
进行导航,此行为都是一致的,因为 NavigationComponent
依赖于 FragmentManager
。在此示例中,如果用户未在表单中输入文本,导致“您确定要...”回调被停用,则系统会运行此回调。
最后,super.onBackPressed()
是系统级回调,如果上述回调被停用,则会再次运行。为了触发“返回主屏幕”、跨 activity 和跨任务等系统动画,supportFragmentManager
的返回堆栈必须为空,以便停用其内部回调。
测试预测性返回手势动画
如果您仍在使用 Android 13 或 Android 14,可以测试图 1 中所示的返回主屏幕动画。
如需测试此动画,请完成以下步骤:
在您的设备上,依次转到设置 > 系统 > 开发者选项。
选择预测性返回手势动画。
启动更新后的应用,然后执行返回手势,看看实际运行效果。