添加对预测性返回手势的支持

图 1. 预测性返回手势在手机上的视觉效果和风格模拟

预测性返回是一项手势导航功能,可让用户在完成返回滑动操作前,就能提前预览即将跳转至的界面。

例如,使用返回手势可以在应用后面显示主屏幕的动画预览,如图 1 中的模型所示。

从 Android 15 开始,预测性返回动画的开发者选项不再可用。现在,如果应用已选择完全启用或在 activity 级别启用预测性返回手势,则会显示“返回主屏幕”、跨任务和跨 activity 等系统动画。

您可以测试这种返回主屏幕动画(如本页的后续部分所述)。

如需支持预测性返回手势,您需要使用 AndroidX Activity 1.6.0 或更高版本的 API 中向后兼容的 OnBackPressedCallback,或使用新的 OnBackInvokedCallback 平台 API 更新应用。大多数应用都使用向后兼容的 AndroidX API。

此更新提供了一种迁移路径,可正确拦截返回导航,包括在 KeyEvent.KEYCODE_BACK 和任何使用 onBackPressed 方法的类(例如 ActivityDialog)中,将返回拦截替换成新的系统 Back API。

Codelab 和 Google I/O 大会视频

除了参考本页的文档外,您还可以试用我们的 Codelab, 其中提供了使用 AndroidX Activity API 处理预测性返回手势的常见 WebView 用例实现。

您还可以观看我们的 Google I/O 视频,其中介绍了实现 AndroidX 和平台 API 的其他示例。

在 Compose 中处理自定义返回手势

Compose 提供了 PredictiveBackHandler 可组合项来处理自定义返回手势。此 API 可让您响应返回手势,并提供一个 FlowBackEventCompat 对象,您可以使用这些对象在用户滑动时实现自定义动画或过渡效果。

如需使用 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,请执行以下操作:

  1. 通过实现 OnBackPressedCallback 将系统返回导航处理逻辑迁移到 AndroidX 的 OnBackPressedDispatcher。如需获得详细指导,请参阅提供自定义返回导航

  2. 当已为停止拦截返回手势做好准备时,停用 OnBackPressedCallback

  3. 停止使用 OnBackPressedKeyEvent.KEYCODE_BACK 拦截返回事件。

  4. 请务必升级到 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 之前的版本不支持的 onBackPressed API。
  • 在应用级别设置 enableOnBackInvokedCallback 标志会为应用中的所有 activity 建立默认值。您可以在 activity 级别设置标志来替换每个 activity 的默认值,如前面的代码示例所示。

回拨指南

使用受支持的系统返回回调(PredictiveBackHandlerBackHandler [适用于 Compose]、OnBackPressedCallbackOnBackInvokedCallback)时,请遵循以下准则。

确定用于启用和停用每个回调的界面状态

界面状态是描述界面的属性。我们建议您遵循以下简要步骤。

  1. 确定用于启用和停用每个回调的界面状态。

  2. 使用可观察数据容器类型(例如 StateFlow 或 Compose State)定义该状态,并在状态更改时启用或停用回调。

如果您的应用之前已将返回逻辑与条件语句相关联,这可能表示您是在返回事件发生后才做出回应。请避免使用这种模式,而改用较新的回调。 如果可能,请将回调移出条件语句,并改为将回调与可观察数据容器类型关联起来。

对界面逻辑使用系统返回回调

界面逻辑决定着如何显示界面。您可以使用系统返回回调运行界面逻辑,例如显示对话框或运行动画。

如果您的应用启用了 OnBackPressedCallbackOnBackInvokedCallback(带有 PRIORITY_DEFAULTPRIORITY_OVERLAY),则预测性返回动画不会运行,并且您必须处理返回事件。请勿创建这些回调来运行业务逻辑或进行日志记录。

如果您的应用必须在用户向后滑动时运行业务逻辑或记录日志,请使用以下方法:

  • 在 Compose 中:在与 Compose 目的地关联的 ViewModelonCleared() 回调中记录。这是了解 Compose 目的地何时从返回堆栈中弹出并销毁的最佳信号。
  • 在 Android 16 及更高版本中:将 OnBackInvokedCallbackPRIORITY_SYSTEM_NAVIGATION_OBSERVER 搭配使用。这会创建一个不使用返回事件的观察者回调。例如,您可以在用户从根 activity(离开您的应用)向后滑动时注册此回调,以记录返回事件或运行业务逻辑,同时仍允许播放返回主屏幕动画。
  • 在基于视图的应用中:在生命周期或返回堆栈回调中记录,而不是使用返回事件:
    • 对于 activity 过渡,请检查 isFinishing 是否为 Activity.onDestroy() 中的 true
    • 对于 fragment 过渡,请检查 isRemoving 在 fragment 的视图生命周期 onDestroy() 内是否为 true,或者使用 FragmentManager.OnBackStackChangedListeneronBackStackChangeStarted/onBackStackChangeCommitted)。

创建单一责任回调

您可以向调度程序添加多个回调。这些回调将添加到堆栈中,其中最近添加的已启用回调会处理下一个返回手势,且每个返回手势对应一个回调。

如果回调具有单一职责,则更容易管理回调的启用状态。例如:

Compose 中堆栈中回调的顺序。
图 2. Compose 中的回调堆栈图。

图 2 显示了堆栈中可以有多个回调,每个回调负责一项任务。在 Compose 中,系统会从最内层的可组合项到最外层的可组合项评估回调,并且只有当堆栈中前面的回调处于停用状态时,回调才会运行:

  • “确定要…吗?”当用户在表单中输入数据时,PredictiveBackHandler 会启用,否则会停用。启用后,它会拦截返回手势,以显示确认对话框或自定义应用内动画。
  • 如果前面的回调处于停用状态,则运行屏幕级 BackHandler。在此示例中,该功能处于停用状态。
  • 如果前面的自定义回调处于停用状态,NavHost 回调会处理返回导航,以从返回堆栈中弹出目的地。
  • 最后,如果所有前面的回调均处于停用状态,系统会处理返回手势。当返回堆栈位于其根目的地时,系统会触发系统级动画,例如“返回主屏幕”、跨 Activity 和跨任务的动画。

基于 View 的应用也适用相同的堆栈行为:最近添加的已启用 OnBackPressedCallback 具有优先权,然后依次回退到 FragmentManager 和最终的系统返回处理。

测试预测性返回手势动画

从 Android 15 开始,对于支持预测性返回导航的应用,系统动画(例如“返回主屏幕”、跨任务和跨 activity 动画)默认处于启用状态。它们不再受开发者选项的限制。

在搭载 Android 13 或 Android 14 的设备上,您可以启用开发者选项来测试图 1 中所示的返回主屏幕动画:

  1. 在您的设备上,依次转到设置 > 系统 > 开发者选项

  2. 选择预测性返回手势动画

  3. 启动更新后的应用,然后执行返回手势,看看实际运行效果。