Android 14(API 级别 34)添加了对其他系统动画和 API 的支持,以创建自定义动画。有关更多信息,请参阅 添加对内置和自定义预测后退动画的支持。
例如,使用后退手势可以在应用后面显示主屏幕的动画预览,如图 1 中的模型所示。从 Android 13 开始,您可以通过启用开发者选项(如本页所述)测试此后退到主屏幕动画。
支持预测后退手势需要更新您的应用,使用向后兼容的 OnBackPressedCallback
AppCompat 1.6.0-alpha05(AndroidX)或更高 API,或使用新的 OnBackInvokedCallback
平台 API。大多数应用将使用向后兼容的 AndroidX API。
此更新提供了一条迁移路径以正确拦截后退导航,这涉及到用新的系统后退 API 替换来自 KeyEvent.KEYCODE_BACK
和任何具有 onBackPressed
方法的类(如 Activity
和 Dialog
)的后退拦截。
Codelab 和 Google I/O 视频
除了在本页面查阅此文档外,还可以尝试我们的代码实验室。它提供了 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,但无法迁移 | 延迟启用,直到此功能成为必选功能。 |
迁移 AndroidX 后退导航实现
此用例最常见(也是最推荐的)。它适用于使用OnBackPressedDispatcher
实现自定义手势导航处理的新应用或现有应用,如提供自定义后退导航中所述。
如果您的应用属于此类别,请按照以下步骤添加对预测性后退手势的支持
为了确保已经使用
OnBackPressedDispatcher
API(例如 Fragment 和 Navigation Component)的 API 与预测性后退手势无缝协作,请升级到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 的 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
注册您的自定义后退逻辑。这可以防止当前活动结束,并且您的回调有机会在用户完成系统后退导航后对后退操作做出反应。准备好停止拦截后退手势时,取消注册
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
拦截后退事件。成功迁移应用后,启用预测性后退手势(如本页面所述),以便
OnBackInvokedCallback
生效。
您可以使用PRIORITY_DEFAULT
或PRIORITY_OVERLAY
注册OnBackInvokedCallback
,这在类似的 AndroidX OnBackPressedCallback
中不可用。在某些情况下,注册具有PRIORITY_OVERLAY
的回调非常有用。一个适用此情况的示例是当您从onKeyPreIme()
迁移并且您的回调需要接收后退手势而不是打开的 IME 时。IME 在打开时会使用PRIORITY_DEFAULT
注册回调。使用PRIORITY_OVERLAY
注册您的回调,以确保OnBackInvokedDispatcher
将后退手势分派到您的回调而不是打开的 IME。
启用预测性后退手势
确定了如何根据您的情况更新应用后,请启用对预测性后退手势的支持。
要启用,请在AndroidManifest.xml
的<application>
标签中,将android:enableOnBackInvokedCallback
标志设置为true
。
<application
...
android:enableOnBackInvokedCallback="true"
... >
...
</application>
如果您不提供值,则默认为false
,并执行以下操作
- 禁用预测性后退手势系统动画。
- 忽略
OnBackInvokedCallback
,但OnBackPressedCallback
调用继续工作。
在活动级别启用
从 Android 14 开始,android:enableOnBackInvokedCallback
标志允许您在活动级别启用预测性系统动画。此行为使大型多活动应用更容易迁移到预测性后退手势。
以下代码显示了使用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>
在前面的示例中,为".SecondActivity"
设置android:enableOnBackInvokedCallback=true
将启用跨活动的系统动画。
使用android:enableOnBackInvokedCallback
标志时,请记住以下注意事项
- 设置
android:enableOnBackInvokedCallback=false
将在活动级别或应用级别关闭预测性后退动画(具体取决于您设置标签的位置),并指示系统忽略对OnBackInvokedCallback
平台 API 的调用。但是,对OnBackPressedCallback
的调用将继续运行,因为OnBackPressedCallback
向后兼容并调用onBackPressed
API,该 API 在 Android 13 之前不受支持。 - 在应用级别设置
enableOnBackInvokedCallback
标志将为应用中的所有活动建立默认值。您可以通过在活动级别设置该标志来覆盖每个活动的默认值,如前面的代码示例所示。
回调最佳实践
以下是使用受支持的系统后退回调的最佳实践;BackHandler
(用于 Compose)、OnBackPressedCallback
或OnBackInvokedCallback
。
确定启用和禁用每个回调的 UI 状态
UI 状态是描述 UI 的属性。我们建议遵循以下高级步骤。
确定启用和禁用每个回调的 UI 状态。
使用可观察数据持有者类型(例如
StateFlow
或 Compose State)定义该状态,并在状态更改时启用或禁用回调。
如果您的应用以前将后退逻辑与条件语句相关联,这可能表示您在后退事件已发生后才对其做出反应,这是您应该避免使用较新回调的模式。如果可能,请将回调移到条件语句之外,而是将其与可观察数据持有者类型相关联。
将系统后退回调用于 UI 逻辑
UI 逻辑决定了如何显示 UI。使用系统后退回调运行 UI 逻辑,例如显示弹出窗口或运行动画。
如果您的应用启用了系统后退回调,则预测性动画不会运行,您必须处理后退事件。不要仅为了运行非 UI 逻辑而创建回调。
例如,如果您仅拦截后退事件以进行日志记录,请在 Activity 或 Fragment 生命周期内进行日志记录。
- 对于活动到活动的情况或片段到活动的情况,如果 Activity 生命周期的
onDestroy
中的isFinishing
为true
,则记录日志。 - 对于片段到片段的情况,如果 Fragment 视图生命周期的
onDestroy
中的isRemoving
为 true,则记录日志;或者,使用FragmentManager.OnBackStackChangedListener
中的onBackStackChangeStarted
或onBackStackChangeCommitted
方法记录日志。
对于 Compose 案例,请在与 Compose 目标关联的ViewModel
的onCleared()
回调中记录日志。这是了解 Compose 目标何时从后退堆栈中弹出并销毁的最佳信号。
创建单一职责回调
这是可能的,因为您可以向调度程序添加多个回调。回调被添加到一个堆栈中,其中最后添加的已启用回调将处理下一个后退手势,每个后退手势一个回调。
测试预测性后退手势动画
从 Android 13 正式版开始,您应该能够启用一个开发者选项来测试图 1 中显示的返回主页动画。
要测试此动画,请完成以下步骤
在您的设备上,转到**设置 > 系统 > 开发者选项**。
选择**预测性返回动画**。
启动您更新后的应用,并使用返回手势查看其运行效果。