NavOptionsBuilder.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.AnimRes
import androidx.annotation.AnimatorRes
import androidx.annotation.IdRes
@DslMarker
public annotation class NavOptionsDsl
/**
* Construct a new [NavOptions]
*/
public fun navOptions(optionsBuilder: NavOptionsBuilder.() -> Unit): NavOptions =
NavOptionsBuilder().apply(optionsBuilder).build()
/**
* DSL for constructing a new [NavOptions]
*/
@NavOptionsDsl
public class NavOptionsBuilder {
private val builder = NavOptions.Builder()
/**
* Whether this navigation action should launch as single-top (i.e., there will be at most
* one copy of a given destination on the top of the back stack).
*
* This functions similarly to how [android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP]
* works with activites.
*/
public var launchSingleTop: Boolean = false
/**
* Whether this navigation action should restore any state previously saved
* by [PopUpToBuilder.saveState] or the `popUpToSaveState` attribute. If no state was
* previously saved with the destination ID being navigated to, this has no effect.
*/
@get:Suppress("GetterOnBuilder", "GetterSetterNames")
@set:Suppress("SetterReturnsThis", "GetterSetterNames")
public var restoreState: Boolean = false
/**
* Returns the current destination that the builder will pop up to.
*/
@IdRes
public var popUpToId: Int = -1
internal set(value) {
field = value
inclusive = false
}
/**
* Pop up to a given destination before navigating. This pops all non-matching destinations
* from the back stack until this destination is found.
*/
@Deprecated("Use the popUpToId property.")
public var popUpTo: Int
get() = popUpToId
@Deprecated("Use the popUpTo function and passing in the id.")
set(value) {
popUpTo(value)
}
/**
* Pop up to a given destination before navigating. This pops all non-matching destinations
* from the back stack until this destination is found.
*/
public var popUpToRoute: String? = null
private set(value) {
if (value != null) {
require(value.isNotBlank()) { "Cannot pop up to an empty route" }
field = value
inclusive = false
}
}
private var inclusive = false
private var saveState = false
/**
* Pop up to a given destination before navigating. This pops all non-matching destinations
* from the back stack until this destination is found.
*/
public fun popUpTo(@IdRes id: Int, popUpToBuilder: PopUpToBuilder.() -> Unit = {}) {
popUpToId = id
popUpToRoute = null
val builder = PopUpToBuilder().apply(popUpToBuilder)
inclusive = builder.inclusive
saveState = builder.saveState
}
/**
* Pop up to a given destination before navigating. This pops all non-matching destination routes
* from the back stack until the destination with a matching route is found.
*
* @param route route for the destination
* @param popUpToBuilder builder used to construct a popUpTo operation
*/
public fun popUpTo(route: String, popUpToBuilder: PopUpToBuilder.() -> Unit = {}) {
popUpToRoute = route
popUpToId = -1
val builder = PopUpToBuilder().apply(popUpToBuilder)
inclusive = builder.inclusive
saveState = builder.saveState
}
/**
* Sets any custom Animation or Animator resources that should be used.
*
* Note: Animator resources are not supported for navigating to a new Activity
*/
public fun anim(animBuilder: AnimBuilder.() -> Unit) {
AnimBuilder().apply(animBuilder).run {
this@NavOptionsBuilder.builder.setEnterAnim(enter)
.setExitAnim(exit)
.setPopEnterAnim(popEnter)
.setPopExitAnim(popExit)
}
}
internal fun build() = builder.apply {
setLaunchSingleTop(launchSingleTop)
setRestoreState(restoreState)
if (popUpToRoute != null) {
setPopUpTo(popUpToRoute, inclusive, saveState)
} else {
setPopUpTo(popUpToId, inclusive, saveState)
}
}.build()
}
/**
* DSL for customizing [NavOptionsBuilder.popUpTo] operations.
*/
@NavOptionsDsl
public class PopUpToBuilder {
/**
* Whether the `popUpTo` destination should be popped from the back stack.
*/
public var inclusive: Boolean = false
/**
* Whether the back stack and the state of all destinations between the
* current destination and the [NavOptionsBuilder.popUpTo] ID should be saved for later
* restoration via [NavOptionsBuilder.restoreState] or the `restoreState` attribute using
* the same [NavOptionsBuilder.popUpTo] ID (note: this matching ID is true whether
* [inclusive] is true or false).
*/
@get:Suppress("GetterOnBuilder", "GetterSetterNames")
@set:Suppress("SetterReturnsThis", "GetterSetterNames")
public var saveState: Boolean = false
}
/**
* DSL for setting custom Animation or Animator resources on a [NavOptionsBuilder]
*/
@NavOptionsDsl
public class AnimBuilder {
/**
* The custom Animation or Animator resource for the enter animation.
*
* Note: Animator resources are not supported for navigating to a new Activity
*/
@AnimRes
@AnimatorRes
public var enter: Int = -1
/**
* The custom Animation or Animator resource for the exit animation.
*
* Note: Animator resources are not supported for navigating to a new Activity
*/
@AnimRes
@AnimatorRes
public var exit: Int = -1
/**
* The custom Animation or Animator resource for the enter animation
* when popping off the back stack.
*
* Note: Animator resources are not supported for navigating to a new Activity
*/
@AnimRes
@AnimatorRes
public var popEnter: Int = -1
/**
* The custom Animation or Animator resource for the exit animation
* when popping off the back stack.
*
* Note: Animator resources are not supported for navigating to a new Activity
*/
@AnimRes
@AnimatorRes
public var popExit: Int = -1
}