1. 简介
上次更新日期:2022 年 4 月 11 日
在 Android 13 中,我们添加了相关 API,为即将推出的 _predictive“返回”手势提供支持。
借助此功能,用户可以在完成整个“返回”手势之前预览该手势的结果。这样一来,在 WebView 中,用户基本上就可以决定是留在当前视图中,还是完成操作并返回主屏幕、之前的 activity 或之前访问过的页面。其效果示例如下:
在此 Codelab 中,我们将修复一个实现 WebView 的调查问卷 fragment。
此 Codelab 的目标
此 Codelab 为您展示了对于会拦截系统“返回”导航的 AndroidX 应用,如何将其迁移到支持在 WebView 中使用预测性“返回”手势,从而做好准备以应对 Android 系统未来的变更。
如果您的应用使用默认的系统“返回”导航(也就是说,它不会拦截系统“返回”导航),您只需选择启用 enableOnBackInvokedCallback
即可。完成以上操作后,在预测性“返回”手势推出后,您的应用就会开始使用该手势。
构建内容
在此 Codelab 中,您将使用 AndroidX API 库在 Sunflower 应用中处理“返回”手势。
学习内容
- 如何拦截 AndroidX 的 on-back 调用
- 如何将“返回”事件返回到系统
- 处理"返回手势的其他选项
- Android 13 及更高版本中的全新用户体验(提供更具预测性的“返回”手势导航)
所需条件
- Android Studio
- (可选)Git
2. 规划对预测性“返回”手势的支持
使用 AndroidX API 实现此功能
此 Codelab 专为已在使用 AndroidX 的应用而设计。
您将实现 OnBackPressedDispatcher
和 OnBackPressedCallback
以支持“返回”导航。
其他选项
根据您的应用可能具有的不同需求,我们还提供了其他选项用于处理此功能:
- 对于无法使用 AndroidX 的应用 - 如果您遇到这种麻烦,我们为您提供了解决方案。使用我们将在 Android 13 中引入的新的
OnBackInvokedDispatcher
和OnBackInvokedCallback
平台类,让您无需 AndroidX 即可使用这些 ahead-of-time API。如需了解详细信息,请参阅文档。 - 对于暂时无法迁移的应用 - 如果您遇到这种麻烦,我们也为您提供了解决方案。如果暂时无法迁移到 AndroidX 库或平台 API,您可以选择停用预测性“返回”手势。如需了解详细信息,请参阅文档。
3.准备工作
安装 Android Studio
安装 Android Studio 和 Android 13 SDK。
获取设备
您可以使用虚拟或实体 Android 设备运行您使用此 Codelab 构建的应用。
启用手势导航
如果您运行使用 API 级别 29 的新模拟器实例,手势导航可能默认处于未启用状态。如需启用手势导航,请依次选择 System settings > System > System Navigation > Gesture Navigation。
获取代码
请通过以下任一方式获取代码:
下载 ZIP 文件
通过 Git 下载
如果您希望使用 Git 下载代码,请按以下步骤操作:
- 安装 Git。
- 克隆
starter-code
或main
分支,以获取此练习的应用:
终端
// 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
运行应用
请完成以下步骤:
- 在 Android Studio 中打开并构建应用。
- 创建新的虚拟设备,并选择 Tiramisu。或者,您也可以连接搭载 API 级别 33 或更高级别的实体设备。
- 运行 Sunflower 应用。
接下来,您将建立基准,并了解 Sunflower 应用提供的不良体验。
4. 建立基准
我们的起点是 Sunflower 应用,其中包含一个在 WebView 中展示的调查问卷,该 WebView 在处理“返回”手势时表现不佳。当用户在 WebView 中从左侧或右侧边缘进行滑动以返回时,应用会让用户返回之前的 fragment,而不是返回上一个页面,导致用户丢失所有未提交的数据。
浏览演示
从主屏幕开始,我们将演示应用的主要工作流,以查看 WebView 功能带来的糟糕体验。
- 在 Sunflower 应用的默认屏幕中,点按 PLANT LIST。
- 在植物目录中,点按任意植物。(在本示例中,我们将使用牛油果。)
- 在您点按的植物的信息屏幕中,点按拇指朝上图标(位于右上角)为植物评分。
- 开始填写调查问卷,但到第 3 题就停止回答。
- 从左侧(或右侧)边缘向内滑动以使用“返回”手势。请注意,完成“返回”滑动手势后,您不会进入调查问卷中的第 2 题,而是会进入植物详细信息 fragment(在本示例中,就是“牛油果”信息页面)。这会导致您的答案丢失,而且会造成糟糕的用户体验。
现在,我们来修复这些问题!
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 导航是否能够正常运行。
- 在 Android Studio 中,再次构建并运行应用。
- 与首次运行演示时一样,点按您选择的植物,然后点按拇指朝上图标,接着填写调查问卷,直到第 3 题。
- 从左侧(或右侧)边缘向内滑动以使用“返回”手势。WebView 应该会返回调查问卷中的第 2 题。
这正是我们想要实现的行为。不过,工作只完成了一半,问题还没完全修复。继续操作您就能明白这句话的意思了:
- 从第 2 题滑动返回第 1 题,然后再滑动返回一次,尝试返回植物详细信息 fragment。
请注意,您无法从第 1 题返回植物详细信息 fragment。原因如下:
- 使用 on-back 导航时,您的 WebView 会通过避免离开 WebView 来处理“返回”导航。
- 当应用不再需要“返回”导航时,应用需要将该导航返回到系统。让我们进入下一部分,修复这个问题!
6. 修复“返回”手势
在上一步中,我们的应用拦截了“返回”手势,而没有将其返回到前几步中的植物详细信息 fragment。因此,我们的用户无法离开应用,并会在 WebView 中卡住,这就导致用户体验十分糟糕。
使用 OnBackPressedCallback 启用或停用“返回”导航
- 替换
doUpdateVisitedHistory
方法以确定是否应该拦截“返回”导航。处理“返回”导航的逻辑如下:- 如果 WebView (
webView.canGoBack()
) 中还有更多要返回的页面,则应启用OnBackPressedCallback
方法。 - 相反,如果 WebView 中没有更多要返回的页面,则应停用
OnBackPressedCallback
方法。因此,“返回”手势将返回到返回堆栈中最顶层的 fragment。
- 如果 WebView (
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()
}
}
}
- 如需再次测试 WebView,请再次填写调查问卷,直到第 3 题。
- 使用“返回”手势,一直返回到植物详细信息视图。您应该能够顺利执行此操作。
以下示例展示了修复之后的效果:
7. 恭喜
恭喜!您已经学习了很多内容。我们希望您已经更好地了解了相关选项和 API,以便开始将您的应用更新为支持 Android 中提供的预测性“返回”手势。
该手势在未来 Android 版本中的效果
在即将推出的 Android 版本中,您将开始体验预测性“返回”手势,如以下动画所示。我们强烈建议您尽快开始实现这些更改!
所学内容
- 如何使您的应用开始使用支持预测性“返回”手势的 API
- 如何拦截 AndroidX 的 on-back 调用
- 如何将“返回”导航返回到系统
- 处理“返回”手势的其他选项
- Android 13 中的全新用户体验(提供更具预测性的“返回”手势导航)