预测性返回是一项手势导航功能,可让用户在完成返回滑动操作前,就能提前预览即将跳转至的界面。
例如,使用返回手势可以在应用后面显示主屏幕的动画预览,如图 1 中的模型所示。
从 Android 15 开始,预测性返回动画的开发者选项不再可用。现在,如果应用已选择完全启用或在 activity 级别启用预测性返回手势,则会显示“返回主屏幕”、跨任务和跨 activity 等系统动画。
您可以测试这种返回主屏幕动画(如本页的后续部分所述)。
如需支持预测性返回手势,您需要使用 AndroidX Activity 1.6.0 或更高版本的 API 中向后兼容的 OnBackPressedCallback,或使用新的 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,请确保您的应用包含 androidx.activity:activity-compose 依赖项(版本 1.8.0 或更高版本):
// In your build.gradle.kts file:
dependencies {
implementation("androidx.activity:activity-compose:1.8.0")
}
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 或更高版本。
更新使用自定义返回导航的应用
如果您的应用实现了自定义返回行为,则会有不同的迁移路径,具体取决于它是否使用了 AndroidX 以及它如何处理返回导航。
| 您的应用会如何处理返回导航 | 推荐的迁移路径(此页面上的链接) |
| AndroidX APIs | 迁移现有的 AndroidX 返回实现 |
| 不受支持的平台 API | 将包含不受支持的返回导航 API 的 AndroidX 应用迁移至 AndroidX API |
迁移 AndroidX 返回导航实现
此用例最常见(也最推荐)。它适用于使用 OnBackPressedDispatcher 实现自定义手势导航处理功能的新应用或现有应用,如提供自定义返回导航中所述。
为了确保已在使用 OnBackPressedDispatcher 的 API(例如 fragment 和 Navigation 组件)能够与预测性返回手势完美配合,请升级到 AndroidX Activity 1.6.0 或更高版本。
// In your build.gradle file:
dependencies {
// Add this in addition to your other dependencies
implementation "androidx.activity:activity:1.6.0"
}
将包含不受支持的返回导航 API 的 AndroidX 应用迁移至 AndroidX API
如果您的应用使用 AndroidX 库,但会实现或引用不受支持的返回导航 API,则需要改用 AndroidX API 来支持新行为。
如需将不受支持的 API 迁移到 AndroidX API,请执行以下操作:
通过实现
OnBackPressedCallback将系统返回导航处理逻辑迁移到 AndroidX 的OnBackPressedDispatcher。如需获得详细指导,请参阅提供自定义返回导航。当已为停止拦截返回手势做好准备时,停用
OnBackPressedCallback。停止使用
OnBackPressed或KeyEvent.KEYCODE_BACK拦截返回事件。请务必升级到 AndroidX Activity 1.6.0 或更高版本。
// In your build.gradle file: dependencies { // Add this in addition to your other dependencies implementation "androidx.activity:activity:1.6.0" }
选择停用预测性返回
如需选择停用预测性返回手势,请在 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),则预测性返回动画不会运行,并且您必须处理返回事件。请勿创建这些回调来运行业务逻辑或进行日志记录。
如果您的应用必须在用户向后滑动时运行业务逻辑或记录日志,请使用以下方法:
- 在 Compose 中:在与 Compose 目的地关联的
ViewModel的onCleared()回调中记录。这是了解 Compose 目的地何时从返回堆栈中弹出并销毁的最佳信号。 - 在 Android 16 及更高版本中:将
OnBackInvokedCallback与PRIORITY_SYSTEM_NAVIGATION_OBSERVER搭配使用。这会创建一个不使用返回事件的观察者回调。例如,您可以在用户从根 activity(离开您的应用)向后滑动时注册此回调,以记录返回事件或运行业务逻辑,同时仍允许播放返回主屏幕动画。 - 在基于视图的应用中:在生命周期或返回堆栈回调中记录,而不是使用返回事件:
- 对于 activity 过渡,请检查
isFinishing是否为Activity.onDestroy()中的true。 - 对于 fragment 过渡,请检查
isRemoving在 fragment 的视图生命周期onDestroy()内是否为true,或者使用FragmentManager.OnBackStackChangedListener(onBackStackChangeStarted/onBackStackChangeCommitted)。
- 对于 activity 过渡,请检查
创建单一责任回调
您可以向调度程序添加多个回调。这些回调将添加到堆栈中,其中最近添加的已启用回调会处理下一个返回手势,且每个返回手势对应一个回调。
如果回调具有单一职责,则更容易管理回调的启用状态。例如:
图 2 显示了堆栈中可以有多个回调,每个回调负责一项任务。在 Compose 中,系统会从最内层的可组合项到最外层的可组合项评估回调,并且只有当堆栈中前面的回调处于停用状态时,回调才会运行:
- “确定要…吗?”当用户在表单中输入数据时,
PredictiveBackHandler会启用,否则会停用。启用后,它会拦截返回手势,以显示确认对话框或自定义应用内动画。 - 如果前面的回调处于停用状态,则运行屏幕级
BackHandler。在此示例中,该功能处于停用状态。 - 如果前面的自定义回调处于停用状态,
NavHost回调会处理返回导航,以从返回堆栈中弹出目的地。 - 最后,如果所有前面的回调均处于停用状态,系统会处理返回手势。当返回堆栈位于其根目的地时,系统会触发系统级动画,例如“返回主屏幕”、跨 Activity 和跨任务的动画。
基于 View 的应用也适用相同的堆栈行为:最近添加的已启用 OnBackPressedCallback 具有优先权,然后依次回退到 FragmentManager 和最终的系统返回处理。
测试预测性返回手势动画
从 Android 15 开始,对于支持预测性返回导航的应用,系统动画(例如“返回主屏幕”、跨任务和跨 activity 动画)默认处于启用状态。它们不再受开发者选项的限制。
在搭载 Android 13 或 Android 14 的设备上,您可以启用开发者选项来测试图 1 中所示的返回主屏幕动画:
在您的设备上,依次转到设置 > 系统 > 开发者选项。
选择预测性返回手势动画。
启动更新后的应用,然后执行返回手势,看看实际运行效果。