这是一个新的系列文章,我们称之为 "Modern Android Development 技巧",简称为 "MAD Skills"。本系列文章致力于帮助开发者们打造更好的现代 Android 开发体验,敬请关注。
今天为大家发布本系列文章中的第二篇: 导航到对话框目的地,如果您想了解第一篇发布的内容,请点击这里查看本系列的第一篇: 导航组件概览 。
概览
在本系列的 上一篇文章 中,我大致介绍了导航组件以及如何使用导航图。
在这篇文章中,我会介绍如何使用 API 来导航到对话框目的地 (dialog destination)。大部分的导航发生在 Fragment 目的地之间,在 UI 中的 NavHostFragment 对象内部,fragment 会被替换出去。但其实导航到容器外的目的地包括对话框也是可行的。就像我们实现普通的目的地一样,我们也可以使用导航图来实现导航到对话框目的地。
甜甜圈记录应用
我有一个小麻烦: 我超爱甜甜圈。
我希望能记得之前吃的哪些甜甜圈是好吃的,这样下次我就可以再买它们。而对于那些我不喜欢的,我也可以避免再买到它们。但我很健忘,所以问题来了,我如何才能记录如此重要的数据呢?
我知道了: 我要用一个应用!
可惜的是,我竟然在 Play 商店中找不到一个甜甜圈记录的应用 (太不可思议了)。所以我只能自己写一个应用。这个应用会有一个我所有吃过甜甜圈的列表,也包括我记录下的关于它们每一个的信息,比如名字、介绍、或许还有一张照片以及相应的评分。
这将是一个相当简单的应用,它包括两个页面:
- 一个甜甜圈列表页
- 一个可以输入甜甜圈相关信息的表单页,它既可以是关于我要新增到列表中的甜甜圈,也可以是关于我要编辑的已存在列表中的甜甜圈
至于信息编辑页面,我希望能用一个对话框。我想实现在当前 activity 上弹出一个相对轻量级的弹窗,而不是替换掉整个页面。我知道导航组件可以处理目的地,但是那只能替换掉单个 NavHostFragment 中的 fragment,对吗?
对,也不对。导航组件默认的行为确实是替换掉 NavHostFragment 中的 fragment。但是导航组件同样可以处理在 NavHostFragment 之外的对话框目的地。
通过模版创建一个工程
首先,我会展示如何在一个新应用中设定导航的基本元素。然后,我会展示我已经写好的甜甜圈记录应用,这样您可以大致了解这将是一个怎样的应用。 (我叫这个为 Julia Child 技巧。在她多年前的烹饪节目中,Child 女士会先介绍菜谱,紧接着快速地展示完成的菜品,最后才是准备工作以及烹饪等中间冗长乏味的部分)
从 Android Studio 3.6 以后,您可以选择任一新建工程模版来使用导航组件。我发现这样做很方便,即便我最终的界面跟模版应用根本不像,至少模版会帮我处理类似下载合适的依赖,以及创建基础代码和资源等工作。
一开始我们需要在 Android Studio 中创建一个 Basic Activity。这一步我在 上一篇文章 中都介绍过,您可以查阅并获取更多详细信息。这里我们将直接跳到下一步。
对话框目的地
如果注意观察导航图中我们新建的 basic activity,您会发现应用此时有两个目的地,同时也包括了在它们彼此之间跳转的操作 (action)。这两个目的地都是 fragment,模版帮我们实现了在 NavHostFragment 内部替换它们的操作。
Basic Activity 附带两个 fragment 以及在它们之间导航的操作
这基本上就是所有我们需要的,所差的是我们需要目的地是一个我们可以输入甜甜圈详细信息的对话框。为了创建这个目的地,首先我们创建所需要的对话框类。
首先,我们在 UI 中创建一个带文本占位符的布局。在布局资源文件夹下创建一个名为 my_dialog.xml 的文件。然后在这个布局中,添加一个 TextView 并且限制它的四边边距使其保持在容器的正中间。结果应该看起来像下图:
我们创建的简单对话框,包括一个居中的文本占位符
接下来,创建一个 Fragment 用来加载上面创建的布局。在 main 包中创建一个新的 Kotlin 文件并命名为 MyDialog.kt。在该文件中,创建一个继承自 BottomSheetDialogFragment 的子类 MyDialog,并且重写 onCreateView() 以返回一个加载自我们刚刚创建的布局的视图。
class MyDialog : BottomSheetDialogFragment