Navigation学习笔记之四--源码阅读之跳转路径图
2022-07-12 本文已影响0人
紫鹰
navigation的跳转是配置在xml中的,这也是他跳转可视化的原因。那么他是怎么解析到程序中的呢,程序中又是怎样存储的?接下来就来看看他的跳转配置的存储结构。
在navigation的入口类NavController中有一个变量 public open var graph: NavGraph 。根据见名知意命名法则,这就是存储其跳转路径图的地方。果断点进去看一下,事实证明,Google不会让我们失望。
NavGraph的变量只有
public val nodes: SparseArrayCompat<NavDestination> = SparseArrayCompat<NavDestination>()
private var startDestId = 0
private var startDestIdName: String? = null
在NavigatorProvider的build()方法中,将目标列表传递给NavGraph,NavGraph将其存储到nodes集合变量中。
override fun build(): NavGraph = super.build().also { navGraph ->
navGraph.addDestinations(destinations)
if (startDestinationId == 0 && startDestinationRoute == null) {
if (route != null) {
throw IllegalStateException("You must set a start destination route")
} else {
throw IllegalStateException("You must set a start destination id")
}
}
if (startDestinationRoute != null) {
navGraph.setStartDestination(startDestinationRoute!!)
} else {
navGraph.setStartDestination(startDestinationId)
}
}
其中navGraph.addDestinations(destinations)方法为
public fun addDestinations(nodes: Collection<NavDestination?>) {
for (node in nodes) {
if (node == null) {
continue
}
addDestination(node)
}
}
最终调用了
public fun addDestination(node: NavDestination) {
val id = node.id
val innerRoute = node.route
...
if (existingDestination != null) {
existingDestination.parent = null
}
node.parent = this
nodes.put(node.id, node)
}
这里实现了将路径存储起来的过程
看到这里,只看到了nodes的构建过程,还是没看到他的跳转参数哪里来的,这就需要看一下他的父类 NavDestination 了,看一下其父类的成员变量
public var parent: NavGraph? = null
private var idName: String? = null
public var label: CharSequence? = null
private val deepLinks = mutableListOf<NavDeepLink>()
private val actions: SparseArrayCompat<NavAction> = SparseArrayCompat()
public val arguments: Map<String, NavArgument>
这下就熟悉了,这些和xml中的字段都对应起来。
有意思的是,他的一个节点存储了他的父节点,即parent: NavGraph,在actions中的NavAction中,存储了下个节点的id。这是一种树形的数据结构。