更新您的应用以支持未来推出的预测性“返回”手势导航

1. 简介

上次更新日期:2022 年 4 月 11 日

在 Android 13 中,我们添加了相关 API,为即将推出的 _predictive“返回”手势提供支持。

借助此功能,用户可以在完成整个“返回”手势之前预览该手势的结果。这样一来,在 WebView 中,用户基本上就可以决定是留在当前视图中,还是完成操作并返回主屏幕、之前的 activity 或之前访问过的页面。其效果示例如下:

此动画显示了在未来实现相关支持后,用户执行以下\n            操作时的大致效果:用户打开 Chrome 浏览器,\n            在 Android 移动设备上查看 Chrome 浏览器,\n            然后执行“返回”滑动手势,接着看到主屏幕显示\n            在浏览器后方作为下一目的地的情形。

在此 Codelab 中,我们将修复一个实现 WebView 的调查问卷 fragment。

此 Codelab 的目标

此 Codelab 为您展示了对于会拦截系统“返回”导航的 AndroidX 应用,如何将其迁移到支持在 WebView 中使用预测性“返回”手势,从而做好准备以应对 Android 系统未来的变更。

如果您的应用使用默认的系统“返回”导航(也就是说,它不会拦截系统“返回”导航),您只需选择启用 enableOnBackInvokedCallback 即可。完成以上操作后,在预测性“返回”手势推出后,您的应用就会开始使用该手势。

构建内容

在此 Codelab 中,您将使用 AndroidX API 库在 Sunflower 应用中处理“返回”手势。

学习内容

  • 如何拦截 AndroidX 的 on-back 调用
  • 如何将“返回”事件返回到系统
  • 处理"返回手势的其他选项
  • Android 13 及更高版本中的全新用户体验(提供更具预测性的“返回”手势导航)

所需条件

2. 规划对预测性“返回”手势的支持

使用 AndroidX API 实现此功能

此 Codelab 专为已在使用 AndroidX 的应用而设计。

您将实现 OnBackPressedDispatcherOnBackPressedCallback 以支持“返回”导航。

其他选项

根据您的应用可能具有的不同需求,我们还提供了其他选项用于处理此功能:

  • 对于无法使用 AndroidX 的应用 - 如果您遇到这种麻烦,我们为您提供了解决方案。使用我们将在 Android 13 中引入的新的 OnBackInvokedDispatcherOnBackInvokedCallback 平台类,让您无需 AndroidX 即可使用这些 ahead-of-time API。如需了解详细信息,请参阅文档
  • 对于暂时无法迁移的应用 - 如果您遇到这种麻烦,我们也为您提供了解决方案。如果暂时无法迁移到 AndroidX 库或平台 API,您可以选择停用预测性“返回”手势。如需了解详细信息,请参阅文档

3.准备工作

安装 Android Studio

安装 Android StudioAndroid 13 SDK

获取设备

您可以使用虚拟或实体 Android 设备运行您使用此 Codelab 构建的应用。

启用手势导航

如果您运行使用 API 级别 29 的新模拟器实例,手势导航可能默认处于未启用状态。如需启用手势导航,请依次选择 System settings > System > System Navigation > Gesture Navigation

获取代码

请通过以下任一方式获取代码:

下载 ZIP 文件

通过 Git 下载

如果您希望使用 Git 下载代码,请按以下步骤操作:

  1. 安装 Git
  2. 克隆 starter-codemain 分支,以获取此练习的应用:

终端

// Get starter app.
git clone --branch starter-code \
https://github.com/googlecodelabs/handling-back-navigation.git
// Get completed app.
git clone --branch main \
https://github.com/googlecodelabs/handling-back-navigation.git

运行应用

请完成以下步骤:

  1. 在 Android Studio 中打开并构建应用。
  2. 创建新的虚拟设备,并选择 Tiramisu。或者,您也可以连接搭载 API 级别 33 或更高级别的实体设备。
  3. 运行 Sunflower 应用。

info-avocado.png

接下来,您将建立基准,并了解 Sunflower 应用提供的不良体验。

4. 建立基准

我们的起点是 Sunflower 应用,其中包含一个在 WebView 中展示的调查问卷,该 WebView 在处理“返回”手势时表现不佳。当用户在 WebView 中从左侧或右侧边缘进行滑动以返回时,应用会让用户返回之前的 fragment,而不是返回上一个页面,导致用户丢失所有未提交的数据。

浏览演示

从主屏幕开始,我们将演示应用的主要工作流,以查看 WebView 功能带来的糟糕体验。

  1. 在 Sunflower 应用的默认屏幕中,点按 PLANT LIST

info-avocado.png

  1. 在植物目录中,点按任意植物。(在本示例中,我们将使用牛油果。)

plant-catalog.png

  1. 在您点按的植物的信息屏幕中,点按拇指朝上图标(位于右上角)为植物评分。

info-avocado.png

  1. 开始填写调查问卷,但到第 3 题就停止回答。

survey-page-1.png

survey-page-2.png

survey-page-3.png

  1. 从左侧(或右侧)边缘向内滑动以使用“返回”手势。请注意,完成“返回”滑动手势后,您不会进入调查问卷中的第 2 题,而是会进入植物详细信息 fragment(在本示例中,就是“牛油果”信息页面)。这会导致您的答案丢失,而且会造成糟糕的用户体验。

sunflower-back-nav-returns-to-the-plant-detail.gif

现在,我们来修复这些问题!

5. 启用预测性“返回”手势

我们的应用已在使用 AndroidX,因此您将使用“返回”导航 API。这些 API 已支持 ahead-of-time 模型

以 Android 13 为目标平台

在应用的 Studio 项目中,将应用的 build 配置更新为以 Android 13 为目标平台,如以下代码段所示。

build.gradle(项目)

buildscript {
   ext {
       // Sdk and tools
       minSdkVersion = 29
       compileSdkPreview = "Tiramisu"
       targetSdkPreview = "Tiramisu"

...
}

包含 AndroidX 1.6.0-alpha03 依赖项

在 build.gradle 中,将 appCompatVersion 设置为 1.6.0-alpha03

build.gradle(项目)

buildscript {
   ext {

       // App dependencies
       appCompatVersion = '1.6.0-alpha03' // Built original with changes

...
}

启用预测性“返回”手势

如需启用预测性“返回”手势 API,请在清单中将 enableOnBackInvokedCallback 设置为 true

AndroidManifest.xml

<application
   ...
   android:enableOnBackInvokedCallback="true" // Enables this feature.
   ... >
...
</application>

声明并注册 OnBackPressedCallback 以处理“返回”手势

创建回调并替换 handleOnBackPressed 方法以处理“返回”手势。对于 WebView 用例,我们将使用“返回”手势在页面堆栈中不断返回,直到没有更多页面为止。

SurveyFragment.kt

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
...
val onBackPressedCallback = object: OnBackPressedCallback(true) {
  override fun handleOnBackPressed() {
    when {
      webView.canGoBack() -> webView.goBack()
      }
    }
  }
  requireActivity().onBackPressedDispatcher
    .addCallback(onBackPressedCallback)
...
}

测试您构建的内容

现在,您将测试 WebView 导航是否能够正常运行。

  1. 在 Android Studio 中,再次构建并运行应用。
  2. 与首次运行演示时一样,点按您选择的植物,然后点按拇指朝上图标,接着填写调查问卷,直到第 3 题。
  3. 从左侧(或右侧)边缘向内滑动以使用“返回”手势。WebView 应该会返回调查问卷中的第 2 题。

这正是我们想要实现的行为。不过,工作只完成了一半,问题还没完全修复。继续操作您就能明白这句话的意思了:

  1. 从第 2 题滑动返回第 1 题,然后再滑动返回一次,尝试返回植物详细信息 fragment。

sunflower-back-nav-stuck-survey.gif

请注意,您无法从第 1 题返回植物详细信息 fragment。原因如下:

  • 使用 on-back 导航时,您的 WebView 会通过避免离开 WebView 来处理“返回”导航。
  • 当应用不再需要“返回”导航时,应用需要将该导航返回到系统。让我们进入下一部分,修复这个问题!

6. 修复“返回”手势

在上一步中,我们的应用拦截了“返回”手势,而没有将其返回到前几步中的植物详细信息 fragment。因此,我们的用户无法离开应用,并会在 WebView 中卡住,这就导致用户体验十分糟糕。

使用 OnBackPressedCallback 启用或停用“返回”导航

  1. 替换 doUpdateVisitedHistory 方法以确定是否应该拦截“返回”导航。处理“返回”导航的逻辑如下:
    • 如果 WebView (webView.canGoBack()) 中还有更多要返回的页面,则应启用 OnBackPressedCallback 方法。
    • 相反,如果 WebView 中没有更多要返回的页面,则应停用 OnBackPressedCallback 方法。因此,“返回”手势将返回到返回堆栈中最顶层的 fragment。

SurveyFragment.kt

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
  ...
  // Present the HTML form to the user.
  webView.loadUrl("https://atom-summer-cadet.glitch.me/")
  webView.settings.javaScriptEnabled = true
  webView.addJavascriptInterface(WebAppInterface(requireContext()), "Android")

  ...
  requireActivity().onBackPressedDispatcher
    .addCallback(onBackPressedCallback)

  disableOnBackPressedCallback(webView, onBackPressedCallback)
}
...

private fun disableOnBackPressedCallback(webView: WebView, onBackPressedCallback: OnBackPressedCallback) {
  webView.webViewClient = object: WebViewClient() {
    override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) {
      // Disable the on-back press callback if there are no more questions in the
      // WebView to go back to, allowing us to exit the WebView and go back to
      // the fragment.
      onBackPressedCallback.isEnabled = webView.canGoBack()

      }
    }
  }
  1. 如需再次测试 WebView,请再次填写调查问卷,直到第 3 题。
  2. 使用“返回”手势,一直返回到植物详细信息视图。您应该能够顺利执行此操作。

以下示例展示了修复之后的效果:

sunflower-back-nav-fixed.gif

7. 恭喜

恭喜!您已经学习了很多内容。我们希望您已经更好地了解了相关选项和 API,以便开始将您的应用更新为支持 Android 中提供的预测性“返回”手势。

该手势在未来 Android 版本中的效果

在即将推出的 Android 版本中,您将开始体验预测性“返回”手势,如以下动画所示。我们强烈建议您尽快开始实现这些更改!

animation.gif

所学内容

  • 如何使您的应用开始使用支持预测性“返回”手势的 API
  • 如何拦截 AndroidX 的 on-back 调用
  • 如何将“返回”导航返回到系统
  • 处理“返回”手势的其他选项
  • Android 13 中的全新用户体验(提供更具预测性的“返回”手势导航)

其他资料

参考文档