预测性返回是一项手势导航功能,可让用户预览向后滑动时即将前往的位置。
例如,使用返回手势可以在应用后面显示主屏幕的动画预览,如图 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 的其他示例。
在 Compose 中处理自定义返回手势
Compose 提供了 PredictiveBackHandler 可组合项来处理自定义返回手势。此 API 可让您响应返回手势,并提供一个 Flow 的 BackEventCompat 对象,您可以使用这些对象在用户滑动时实现自定义动画或过渡效果。
PredictiveBackHandler(enabled = isBackHandlerEnabled) { progress: Flow<BackEventCompat> ->
try {
progress.collect { backEvent ->
// Update your UI or animation based on backEvent.progress
}
// Handle the final back action (e.g., navigate back)
} catch (e: CancellationException) {
// Back gesture was cancelled, reset your UI
}
}
如果您只需要拦截返回手势,而无需跟踪进度,请使用 BackHandler。
更新使用默认返回导航的应用
预测性返回功能默认处于启用状态。
如果您的应用使用 fragment 或 Navigation 组件,也请升级到 AndroidX Activity 1.6.0-alpha05 或更高版本。
更新使用自定义返回导航的应用
如果您的应用实现了自定义返回行为,则会有不同的迁移路径,具体取决于它是否使用了 AndroidX 以及它如何处理返回导航。
| 您的应用会如何处理返回导航 | 推荐的迁移路径(此页面上的链接) |
| AndroidX APIs | 迁移现有的 AndroidX 返回实现 |
| 不受支持的平台 API | 将包含不受支持的返回导航 API 的 AndroidX 应用迁移至 AndroidX API |
迁移 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"
选择停用预测性返回
如需选择停用预测性返回手势,请在 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 之前的版本不支持的onBackPressedAPI。 - 在应用级别设置
enableOnBackInvokedCallback标志会为应用中的所有 activity 建立默认值。您可以在 activity 级别设置标志来替换每个 activity 的默认值,如前面的代码示例所示。
回调最佳实践
使用 PredictiveBackHandler 或 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 转场效果或其他自定义回调。
相同的堆栈行为也适用于 Compose:最内层的 PredictiveBackHandler 或 BackHandler 具有优先权。
同样,如果上述回调被停用,且相应 FragmentManager 的返回堆栈不为空,则会运行 childFragmentManager 的回调。在此示例中,此内部回调已停用。
同样,如果上述回调被停用,且 supportFragmentManager 的堆栈不为空,则 supportFragmentManager 的内部回调会运行。在此示例中,如果用户未在表单中输入文本,导致“您确定要...”回调被停用,则系统会运行此回调。
最后,如果上述回调被停用,系统会处理返回手势。为了触发系统动画(例如“返回主屏幕”、跨 activity 和跨任务),supportFragmentManager 的返回堆栈必须为空,以便其内部回调处于停用状态。
测试预测性返回手势动画
如果您仍在使用 Android 13 或 Android 14,可以测试图 1 中所示的返回主屏幕动画。
如需测试此动画,请完成以下步骤:
在您的设备上,依次转到设置 > 系统 > 开发者选项。
选择预测性返回手势动画。
启动更新后的应用,然后执行返回手势,看看实际运行效果。