
预测性返回是手势导航功能,可让用户预览返回滑动会带他们到哪里。
例如,使用返回手势可以显示应用背后主屏幕的动画预览,如图 1 所示。
从 Android 15 开始,预测性返回动画的开发者选项不再可用。回主屏幕、跨任务和跨 Activity 等系统动画现在会出现在已完全或在 Activity 级别选择启用预测性返回手势的应用中。
您可以测试此回主屏幕动画(如本页后续部分所述)。
支持预测性返回手势需要更新您的应用,使用向后兼容的 OnBackPressedCallback
AppCompat 1.6.0-alpha05(AndroidX)或更高版本的 API,或者使用新的 OnBackInvokedCallback
平台 API。大多数应用使用向后兼容的 AndroidX API。
此更新提供了正确拦截返回导航的迁移路径,其中涉及将 KeyEvent.KEYCODE_BACK
和任何带有 onBackPressed
方法的类(例如 Activity
和 Dialog
)的返回拦截替换为新的系统返回 API。
Codelab 和 Google I/O 视频
除了使用本页上的文档外,请尝试我们的 codelab。它提供了一个 WebView 处理预测性返回手势的常见用例实现,使用了 AndroidX Activity API。
您还可以观看我们的 Google I/O 视频,其中涵盖了实现 AndroidX 和平台 API 的更多示例。
更新使用默认返回导航的应用
预测性返回默认启用。
如果您的应用使用 Fragment 或 Navigation Component,也请升级到 AndroidX Activity 1.6.0-alpha05 或更高版本。
更新使用自定义返回导航的应用
如果您的应用实现自定义返回行为,则根据其是否使用 AndroidX 以及如何处理返回导航,有不同的迁移路径。
您的应用使用 AndroidX | 您的应用如何处理返回导航 | 推荐的迁移路径(本页上的链接) |
是 | AndroidX API | 迁移现有的 AndroidX 返回实现 |
不支持的平台 API | 将包含不支持的返回导航 API 的 AndroidX 应用迁移到 AndroidX API | |
否 | 不支持的平台 API,但可以迁移 | 将使用不支持的返回导航 API 的应用迁移到平台 API |
不支持的平台 API,但无法迁移 | 通过在您应用的 AndroidManifest.xml 文件的 <application> 或 <activity> 标签中将 android:enableOnBackInvokedCallback 属性设置为 false 来暂时退出。 |
迁移 AndroidX 返回导航实现
此用例最常见(也最推荐)。它适用于使用 OnBackPressedDispatcher
实现自定义手势导航处理的新应用或现有应用,如提供自定义返回导航所述。
为确保已在使用 OnBackPressedDispatcher
的 API(如 Fragment 和 Navigation Component)与预测性返回手势无缝协作,请升级到 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
将您的系统返回处理逻辑迁移到 AndroidX 的
OnBackPressedDispatcher
,并实现OnBackPressedCallback
。有关详细指导,请参阅提供自定义返回导航。准备停止拦截返回手势时,禁用
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 16 开始,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
向后兼容并调用onBackPressed
API,该 API 在 Android 13 之前不受支持。 - 在应用级别设置
enableOnBackInvokedCallback
标志会为应用中的所有 Activity 建立默认值。您可以通过在 Activity 级别设置该标志来覆盖每个 Activity 的默认值,如前述代码示例所示。
回调最佳实践
以下是使用受支持的系统返回回调(BackHandler
(适用于 Compose)、OnBackPressedCallback
或 OnBackInvokedCallback
)的最佳实践。
确定启用和禁用每个回调的 UI 状态
UI 状态是描述 UI 的属性。我们建议遵循以下高级步骤。
确定启用和禁用每个回调的 UI 状态。
使用可观察数据持有者类型(例如
StateFlow
或 Compose State)定义该状态,并随着状态更改启用或禁用回调。
如果您的应用之前将返回逻辑与条件语句相关联,这可能表示您在返回事件已发生后才对其做出反应。使用较新的回调避免这种模式。如果可能,将回调移到条件语句之外,并将其与可观察数据持有者类型相关联。
将系统返回回调用于 UI 逻辑
UI 逻辑决定如何显示 UI。使用系统返回回调运行 UI 逻辑,例如显示弹出窗口或运行动画。
如果您的应用启用系统返回回调,预测性动画将不会运行,您必须处理返回事件。不要仅为了运行非 UI 逻辑而创建回调。
例如,如果您仅为了日志记录而拦截返回事件,请改为在 Activity 或 Fragment 生命周期内进行日志记录。
- 对于 Activity-to-Activity 或 Fragment-to-Activity 的情况,如果 Activity 生命周期内
onDestroy
中的isFinishing
为true
,则进行日志记录。 - 对于 Fragment-to-Fragment 的情况,如果 Fragment 视图生命周期内
onDestroy
中的isRemoving
为 true,则进行日志记录。或者使用FragmentManager.OnBackStackChangedListener
中的onBackStackChangeStarted
或onBackStackChangeCommitted
方法进行日志记录。
对于 Compose 情况,在与 Compose 目标关联的 ViewModel
的 onCleared()
回调中进行日志记录。这是了解 Compose 目标何时从返回堆栈中弹出并销毁的最佳信号。
创建单一职责回调
您可以向分发器添加多个回调。回调被添加到堆栈中,其中最后一个添加的已启用回调处理下一个返回手势,每个返回手势一个回调。
如果回调具有单一职责,则更容易管理回调的启用状态。例如:

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