使用导航组件: 对话框目的地 | MAD Skills
概览
在本系列的上一篇文章中,我大致介绍了导航组件以及如何使用导航图。
甜甜圈记录应用
我有一个小麻烦: 我超爱甜甜圈。
我希望能记得之前吃的哪些甜甜圈是好吃的,这样下次我就可以再买它们。而对于那些我不喜欢的,我也可以避免再买到它们。但我很健忘,所以问题来了,我如何才能记录如此重要的数据呢?
这将是一个相当简单的应用,它包括两个页面:
一个甜甜圈列表页
一个可以输入甜甜圈相关信息的表单页,它既可以是关于我要新增到列表中的甜甜圈,也可以是关于我要编辑的已存在列表中的甜甜圈
通过模版创建一个工程
Julia Child https://en.wikipedia.org/wiki/Julia_Child
对话框目的地
class MyDialog : BottomSheetDialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.my_dialog,
container, false)
}
}
<dialog
android:id=”@+id/myDialog”
android:name=”com.android.samples.navdialogsample.MyDialog”
android:label=”MyDialog” />
另外,我已经就这个问题咨询了 Android Studio 团队。据说这个问题是由于内部依赖搜索的顺序导致的。他们正在修复这个问题。
view.findViewById<Button>(R.id.button_first).setOnClickListener {
findNavController().navigate(
R.id.action_FirstFragment_to_SecondFragment)
}
view.findViewById<Button>(R.id.button_first).setOnClickListener {
findNavController().navigate(
R.id.action_FirstFragment_to_myDialog)
}
DonutTracker 应用实践
"剧透" 警告: 我已经写完了 DonutTracker 应用。我会带您浏览关键的实现步骤,大家可以看到我是如何使用对话框目的地导航的。
DonutTracker 应用 https://github.com/android/architecture-components-samples/tree/main/MADSkillsNavigationSample
首先,这是应用的导航图:
在 DonutTracker 的导航图中有两个目的地
您会发现主页目的地依然存在,只不过叫做 donutList。这是那个包含甜甜圈列表 (使用 RecyclerView) 的 fragment。我还创建了第二个目的地,叫做 donutEntryDialogFragment,这个是用来让用户编辑甜甜圈信息的。
如果我们查看 DonutList 的代码,该 fragment 包含了那个展示列表数据的 RecyclerView,我们可以发现导航是如何被处理的。点击 FloatingActionButton (FAB) 按钮触发了导航到对话框:
binding.fab.setOnClickListener { fabView ->
fabView.findNavController().navigate(DonutListDirections
.actionDonutListToDonutEntryDialogFragment())
}
注意我这里用的是视图绑定来获取 FloatingActionButton 的引用,也即 binding.fab 的引用。
除此之外,我们同样可以在这个文件中看到点击 RecyclerView 中的列表项是如何导航到编辑那一项的对话框的:
donut ->
findNavController().navigate(DonutListDirections
.actionDonutListToDonutEntryDialogFragment(donut.id))
关于上述代码片段,有几点需要注意:
首先,我们在此使用的 navigate() 函数 (使用 Directions 对象导航) 的语法和之前通过 Basic Activity 模版创建的 (导航到一个通过 R.id.action_FirstFragment_to_myDialog 指定的操作) 略有不同。这是因为上述代码片段来自于 DonutTracker 应用的最终版本,在该版本中我使用了 SafeArgs。SafeArgs 可以生成 Directions 代码,这使得目的地之间带有参数传递的跳转实现起来更加容易。
其次,我们从 FAB 导航时 (不需要传递参数给 Directions 对象) 调用 navigate() 方法和从甜甜圈列表中任一列表项导航时 (需要传递 donut.id) 不太一样。这个区别可以让我们决定究竟是创建一个新甜甜圈 (当没有传递参数) 还是编辑已有的甜甜圈 (当传递了 donut.id)。(剧透警告: 我会在接下来的文章中介绍这一主题,您也可以同时查阅完整代码。)
完整代码 https://github.com/android/architecture-components-samples/tree/main/MADSkillsNavigationSample
运行该应用展示了它是如何工作的。如您所见,我已经预先在应用中输入了一些重要的甜甜圈数据:
点击 FAB,我们可以看到一个待输入新甜甜圈信息的对话框:
如果我们点击任一已存在的甜甜圈 (这里我点击了 "fundonut",因为很显然这里的描述需要再润色一下),应用会带我们到同一个对话框目的地,在这里我们可以编辑刚刚点击的甜甜圈的信息。
总结
通过这篇文章我们了解了如何使用内置的导航组件快速地创建一个新应用,并且学习了如何导航到对话框目的地。在接下来的文章中,我们会继续通过开发这个应用为大家展示导航组件的其它功能,当然也同时会实现一个功能更加强大的甜甜圈记录应用。
更多信息
https://www.youtube.com/playlist?list=PLWz5rJ2EKKc91i2QT8qfrfKgLNlJiG1z7
推荐阅读