添加预测式返回动画

1. 开始之前

本 Codelab 将引导您完成为 SociaLite 应用添加预测式返回动画的过程。您将添加返回主屏幕动画、默认应用内动画,并创建自定义应用内动画。最后,您还将学习其他技巧,帮助您为应用添加预测式返回动画。

前提条件

您将在此 Codelab 中学到什么

  • 如何添加以下预测式返回动画
  • 返回主屏幕
  • 默认应用内动画
  • 自定义应用内动画

您需要准备什么

  • 最新版本的 Android Studio。
  • 运行 Android 15 Beta 2 或更高版本的测试设备或模拟器。
  • 在测试设备或模拟器上启用手势导航

2. 获取入门代码

  1. 如果您已完成让您的应用实现全屏显示 Codelab,请跳至添加预测式返回动画部分,因为您已经拥有入门代码。
  2. 从 GitHub 下载入门代码,或克隆仓库并检出 codelab_improve_android_experience_2024 分支。
$ git clone git@github.com:android/socialite.git
$ cd socialite
$ git checkout codelab_improve_android_experience_2024
  1. 在 Android Studio 中打开 SociaLite,并在您的 Android 15 设备或模拟器上运行应用。您将看到如下所示的屏幕

The Chats screen of the SocialLite app.

本 Codelab 旨在紧随让您的应用实现全屏显示 Codelab 之后完成。如果您尚未完成该 Codelab,请在继续之前,至少确保在 MainActivity.kt 文件中启用了全屏显示,因为应用内预测式返回动画在应用全屏显示时效果最佳。

如果不存在,请在 MainActivity.kt 文件中设置内容之前添加 enableEdgetoEdge()。添加此行将允许您继续本 Codelab 的其余部分,尽管您可能会在聊天线程中看到底部 UI 被系统导航栏遮挡。要移除底部 UI 遮挡,请参阅让您的应用实现全屏显示 Codelab。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
   // Ensure to add this line if you haven't already completed the
   // Make your app edge-to-edge codelab.
        enableEdgeToEdge()
        super.onCreate(savedInstanceState)
        setContent {... }
    }
}

实现全屏显示后,SociaLite 如下所示

Gesture navigation in the SociaLite app.

3. 添加返回主屏幕的预测式返回动画

什么是预测式返回?

预测式返回是一项手势导航功能,允许用户在完全完成返回手势之前预览返回手势的结果。它让他们可以决定是继续返回上一视图还是停留在当前视图。

为您的 Android 应用添加预测式返回支持有助于恢复用户信心并提供更优质的体验。

The back-to-home predictive back of the SocialLite app.

如何添加预测式返回支持

要查看尚为返回主屏幕动画添加预测式返回支持的 SociaLite,请按照以下步骤操作

  1. 确保您在聊天页面上。
  2. 向后滑动返回系统主屏幕。您会立即返回主屏幕,而无法预览后滑将转到何处。

The SocialLite app without the back-to-home animations.

在 Android 15 及更早版本中,要为返回主屏幕预测式返回动画添加支持,请在 AndroidManifest.xml 文件中将 android:enableOnBackInvokedCallback 标志设置为 true

// AndroidManifest.xml

<application
  android:name=".SocialApp"
  ...
  android:enableOnBackInvokedCallback="true">
  <activity
    android:name=".MainActivity"
    android:exported="true"
    ...>

要了解这一行代码更改如何影响 SociaLite 中的后滑手势,请按照以下步骤操作

  1. 确保您在聊天页面上。
  2. 缓慢向后滑动返回系统主屏幕。

您可以看到聊天页面后面预览了返回的目标。这就是返回主屏幕预测式返回动画的样子。

The back-to-home predictive back of the SocialLite app.

4. 添加应用内动画

默认应用内动画

要查看尚为应用内动画添加预测式返回支持的 SociaLite,请按照以下步骤操作

  1. 确保您在聊天页面上。
  2. 选择其中一个对话,例如绵羊
  3. 缓慢向后滑动返回聊天页面。

完成返回手势后滑并返回聊天页面后,您会看到交叉淡入淡出动画。

bb2701e3347841d0.gif

要为 SociaLite 的其他部分添加更多预测式返回支持,请按照以下步骤操作

libs.versions.toml 文件中,将导航 Compose 依赖项升级到 androidx.navigation:navigation-compose:2.8.0-alpha07 或更高版本。

// libs.versions.toml

[versions]
...
media3 = "1.2.0"
navigation = "2.8.0-alpha07"
...
  1. 点击 7c2b0d0d8c0fb2c5.png 将项目与 Gradle 文件同步
  2. 重新运行 SociaLite。
  3. 确保您在聊天页面上。
  4. 选择其中一个对话,例如绵羊
  5. 缓慢向后滑动返回聊天页面。向后滑动时,您可以看到聊天页面淡入视图。这就是默认的应用内动画。

The SociaLite app with default in-app predictive back animations.

自定义应用内动画

要创建自定义预测式返回应用内动画,请按照以下步骤操作

  1. ui/Main.kt 文件中找到 NavHost
  2. 添加 popEnterTransitionpopExitTransition 以缩小即将退出的屏幕。此外,transformOrigin 参数确定缩放动画发生的中心点。默认情况下,它是屏幕中心 (0.5f, 0.5f)。您可以调整此值,使缩放从不同的点开始。
// Main.kt
NavHost(
  navController = navController,
  startDestination = "home",
  popEnterTransition = { EnterTransition.None },
  popExitTransition = {
     scaleOut(
       targetScale = 0.9F,
       transformOrigin = TransformOrigin(pivotFractionX = 0.5f, pivotFractionY = 0.5f)
     )
   },
  modifier = modifier,
)
  1. 重新运行 SociaLite。
  2. 确保您在聊天页面上。
  3. 选择其中一个对话,例如绵羊
  4. 缓慢向后滑动返回聊天页面。向后滑动时,绵羊聊天屏幕会缩小,并且聊天页面会在后台预览。

The SociaLite app with custom in-app predictive back animations.

由于从 Accompanist Navigation Animation 库迁移到 AndroidX 库,Navigation Compose 库能够运行动画。通过利用 Navigation Compose 库及其内置的预测式返回支持,您能够添加对预测式返回手势的支持,并提升 Android 应用体验。

5. 可选:其他预测式返回注意事项

这是可选的技巧部分,可能与您的应用相关。

在根(例如,MainActivity.kt)拦截返回事件

如果您的应用在根 Activity(例如 MainActivity.kt)中使用 BackHandler, PredictiveBackHandler,OnBackPressedCallbackOnBackInvokedCallback 拦截返回事件,您的用户将不会看到预测式返回主屏幕动画。

在根 Activity 拦截返回事件的常见用例包括事件日志记录。我们建议在 Fragment 或 Activity 生命周期方法中记录事件,而不是在 Views 的 OnBackPressedCallbackOnBackInvokedCallback> 或 Compose 的 addOnDestinationChangedListener 中记录事件。有关更多信息,请参阅回调最佳实践

对 Fragment 的支持

如果您正在使用 FragmentManager 或 Navigation Component,以下 Fragment API 支持预测式返回,它们使用 AnimatorAndroidX Transitions 和一些 Material Motions,例如 MaterialSharedAxisMaterialFadeThroughMaterialFade

  • setCustomAnimations
  • setEnterTransition
  • setExitTransition
  • setReenterTransition
  • setReturnTransition
  • setSharedElementEnterTransition
  • setSharedElementReturnTransition

AnimationFramework Transitions 受支持。

如果您的应用正在使用其他导航库,请查阅该库的文档,了解它们是否支持预测式返回动画。

对 Material View 组件的支持

在运行 Android 14 及更高版本的设备上,当 android:enableOnBackInvokedCallback manifest 标志启用且 compileSDK 为 API 级别 34 或更高时,Material View 组件支持预测式返回动画。支持的 Material View 组件包括搜索栏、底部抽屉、侧边抽屉和导航抽屉。

对 Material Compose 组件的支持

Material Compose 组件支持预测式返回动画。它们包括

  • SearchBar
  • ModalBottomSheet
  • ModalDrawerSheet/DismissibleDrawerSheet
  • ModalNavigationDrawer/DismissibleNavigationDrawer

确保您正在使用 androidx.compose.material3:material3-*:1.3.0-alpha01 或更高版本的依赖项。当 android:enableOnBackInvokedCallback manifest 标志启用时,SearchBar 和 ModalBottomSheet 会自动进行预测式返回动画。ModalNavigationDrawer/DismissibleNavigationDrawer 和 ModalDrawerSheet/DismissibleDrawerSheet 需要将 drawerState 传递到它们各自的 sheet 内容 composable 中。

Compose 中对共享元素过渡的支持

Shared element transition with predictive back in Navigation Compose

要获得预测式返回支持,请确保您正在使用 navigation-compose 2.8.0-alpha06 或更高版本的依赖项,并将 android:enableOnBackInvokedCallback="true" 标志添加到您的 AndroidManifest.xml 文件中。

6. 获取解决方案代码

AndroidManifest.xml 文件应如下所示

// AndroidManifest.xml

<application
  android:name=".SocialApp"
  ...
  android:enableOnBackInvokedCallback="true">
  <activity
    android:name=".MainActivity"
    android:exported="true"
    ...>

ui/Main.kt 文件中的 NavHost 应如下所示

// Main.kt
NavHost(
  navController = navController,
  startDestination = "home",
  popEnterTransition = { EnterTransition.None },
  popExitTransition = {
     scaleOut(
       targetScale = 0.9F,
       transformOrigin = TransformOrigin(pivotFractionX = 0.5f, pivotFractionY = 0.5f)
     )
   },
  modifier = modifier,
)

并且 libs.versions.toml 文件应如下所示

// libs.versions.toml

[versions]
...
media3 = "1.2.0"
navigation = "2.8.0-alpha07"
...

解决方案代码位于 main 分支中。

要获取解决方案代码,请按照以下步骤操作

  1. 如果您已经下载了 SociaLite,请运行以下命令

git checkout main

  1. 如果您尚未下载 SocialLite,请再次下载代码以查看 main 分支

git clone git@github.com:android/socialite.git

7. 了解更多

Android 开发者文档

Codelab