NavGraphBuilder.kt
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.navigation
import androidx.annotation.IdRes
/**
* Construct a new [NavGraph]
*
* @param id the destination's unique id
* @param startDestination the starting destination for this NavGraph
* @param builder the builder used to construct the graph
*
* @return the newly constructed NavGraph
*/
@Suppress("Deprecation")
@Deprecated(
"Use routes to build your NavGraph instead",
ReplaceWith(
"navigation(startDestination = startDestination.toString(), route = id.toString()) " +
"{ builder.invoke() }"
)
)
public inline fun NavigatorProvider.navigation(
@IdRes id: Int = 0,
@IdRes startDestination: Int,
builder: NavGraphBuilder.() -> Unit
): NavGraph = NavGraphBuilder(this, id, startDestination).apply(builder).build()
/**
* Construct a new [NavGraph]
*
* @param startDestination the starting destination's route for this NavGraph
* @param route the destination's unique route
* @param builder the builder used to construct the graph
*
* @return the newly constructed NavGraph
*/
public inline fun NavigatorProvider.navigation(
startDestination: String,
route: String? = null,
builder: NavGraphBuilder.() -> Unit
): NavGraph = NavGraphBuilder(this, startDestination, route).apply(builder)
.build()
/**
* Construct a nested [NavGraph]
*
* @param id the destination's unique id
* @param startDestination the starting destination for this NavGraph
* @param builder the builder used to construct the graph
*
* @return the newly constructed nested NavGraph
*/
@Suppress("Deprecation")
@Deprecated(
"Use routes to build your nested NavGraph instead",
ReplaceWith(
"navigation(startDestination = startDestination.toString(), route = id.toString()) " +
"{ builder.invoke() }"
)
)
public inline fun NavGraphBuilder.navigation(
@IdRes id: Int,
@IdRes startDestination: Int,
builder: NavGraphBuilder.() -> Unit
): Unit = destination(NavGraphBuilder(provider, id, startDestination).apply(builder))
/**
* Construct a nested [NavGraph]
*
* @param startDestination the starting destination's route for this NavGraph
* @param route the destination's unique route
* @param builder the builder used to construct the graph
*
* @return the newly constructed nested NavGraph
*/
public inline fun NavGraphBuilder.navigation(
startDestination: String,
route: String,
builder: NavGraphBuilder.() -> Unit
): Unit = destination(NavGraphBuilder(provider, startDestination, route).apply(builder))
/**
* DSL for constructing a new [NavGraph]
*/
@NavDestinationDsl
public open class NavGraphBuilder : NavDestinationBuilder<NavGraph> {
/**
* The [NavGraphBuilder]'s [NavigatorProvider].
*/
public val provider: NavigatorProvider
@IdRes private var startDestinationId: Int = 0
private var startDestinationRoute: String? = null
/**
* DSL for constructing a new [NavGraph]
*
* @param provider navigator used to create the destination
* @param id the graph's unique id
* @param startDestination the starting destination for this NavGraph
*
* @return the newly created NavGraph
*/
@Suppress("Deprecation")
@Deprecated(
"Use routes to build your NavGraph instead",
ReplaceWith(
"NavGraphBuilder(provider, startDestination = startDestination.toString(), " +
"route = id.toString())"
)
)
public constructor(
provider: NavigatorProvider,
@IdRes id: Int,
@IdRes startDestination: Int
) : super(provider[NavGraphNavigator::class], id) {
this.provider = provider
this.startDestinationId = startDestination
}
/**
* DSL for constructing a new [NavGraph]
*
* @param provider navigator used to create the destination
* @param startDestination the starting destination's route for this NavGraph
* @param route the graph's unique route
*
* @return the newly created NavGraph
*/
public constructor(
provider: NavigatorProvider,
startDestination: String,
route: String?
) : super(provider[NavGraphNavigator::class], route) {
this.provider = provider
this.startDestinationRoute = startDestination
}
private val destinations = mutableListOf<NavDestination>()
/**
* Build and add a new destination to the [NavGraphBuilder]
*/
public fun <D : NavDestination> destination(navDestination: NavDestinationBuilder<D>) {
destinations += navDestination.build()
}
/**
* Adds this destination to the [NavGraphBuilder]
*/
public operator fun NavDestination.unaryPlus() {
addDestination(this)
}
/**
* Add the destination to the [NavGraphBuilder]
*/
public fun addDestination(destination: NavDestination) {
destinations += destination
}
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)
}
}
}