Skip to content

Quick Tutorials

Kaustubh Patange edited this page May 27, 2021 · 10 revisions

Table of contents

Navigate to Fragment

// initialize Navigator
val navigator = Navigator.with(this, savedStateInstance)
    .setNavigator(FragmentNavigator::class)
    .initialize(findViewById(R.id.fragment_container))
// actual call
navigator.navigate(MyFragment::class)

Note: The host in which Navigator is set up must implement NavigationTransmittor interface to propogate navigator instance to its child fragments.

Navigate to a Fragment but remember the transaction

Why? Because Navigator does not add your fragment transaction to backstack. You must explicitly specify this, so that on pressing back button (or navigating up) would take you back to the previous fragment.

navigator.navigate(MyFragment::class, FragmentNavigator.NavOptions(remember = true))

Navigation with typed arguments

  • Create an argument class (typically a data class).
@Parcelize
data class MyArgs(
    val name: String,
    val age: Int
    // any other types that can be parceled or serialized.
) : BaseArgs(), Parcelable
  • Create the args & navigate to the destination fragment.
val args = MyArgs(
    name = "John",
    age = 20
)

navigator.navigate(MyFragment::class, FragmentNavigator.NavOptions(args = args))
  • Parse the arguments in the destination fragment. The destination fragment must extend from ValueFragment.
class MyFragment : ValueFragment() {
    override fun onViewCreated(...) {
        ...
        if (hasKeyArgs<MyArgs>()) {
            val args = getKeyArgs<MyArgs>()
            println("Name: ${args.name}, Age: ${args.age}")

            // clearArgs() // (optional) to consume args.
        }
    }
}

Navigation with animation

  • There are some built-in animation as well as support for custom animation.
  • This includes the traditional anim transition to the new animator one as well as transition. However, if you don't want to create them, Navigator provides some default ones built on top of this.
  • Check CircularTransform custom animation to circular reveal fragments during a transaction.
// A simple fade transition.
val options = FragmentNavigator.NavOptions(
    animation = Animation.Fade // or SlideInRight, SlideInLeft, etc.
)

// Supported "anim", "animator", or "transition"
val options = FragmentNavigator.NavOptions(
    animation = Animation.Custom(
        destinationEntering = R.anim.slide_from_right,
        currentExiting = R.anim.fade
    )
)

/**
 * Shared element transition.
 * - In xml set android:transitionName on the view eg: cardView (Fragment A)
 * - (Fragment B) set android:transitionName on the view to share the transition eg: "heroCard".
 */
val options = FragmentNavigator.NavOptions(
    animation = Animation.Shared(
        elements = mapOf(
            binding.cardView to "heroCard"
        )
        // optional enter/exit transition (defaults to fade).
    )
)

// Navigate...
navigator.navigate(MyFragment::class, options)

Navigation with single top instance or popUpTo

  • If you've used Jetpack Navigation Component, there is a concept of single top instance or popUpTo when defining action. Basically, it helps you to clear backstack upto certain fragments.

  • In case of singleTopInstance only one instance of such fragment are allowed in backstack. If there are multiple instance of this fragment the previous one will be removed & the current one will be placed.

  • Clearing all previous backstack when navigating,

val options = FragmentNavigator.NavOptions(
    historyOptions = HistoryOptions.ClearHistory
)

navigator.navigateTo(MyFragment::class, options)
  • Maintain single instance of the fragment,
val options = FragmentNavigator.NavOptions(
    historyOptions = HistoryOptions.SingleTopInstance
)

navigator.navigateTo(MyFragment::class, options)
  • Clear history up to specific Fragment class or backstack name,
val options = FragmentNavigator.NavOptions(
    historyOptions = HistoryOptions.PopToFragment(PreviousFragment::class, all = false) // or PopToBackStack
)

navigator.navigateTo(MyFragment::class, options)

Navigate to a BottomSheet or Dialog Fragment

  • From the host
navigator.show(MyBottomSheetDialog::class, ...)
  • From the child fragment
getParentNavigator().show(MyBottomSheetDialog::class, ...) // this uses parent's FragmentManager.
// or
getSimpleNavigator().show(MyBottomSheetDialog::class, ...) // this uses child's FragmentManager (recommended).
class MyBottomSheetDialog : BottomSheetDialogFragment() {
    override fun onViewCreated(...) {
        ...
        // optional arguments you can pass when calling navigator.show()
        if (hasKeyArgs<MyArgs>()) {
            val args = getKeyArgs<MyArgs>()
            // process arguments..
        }
    }
}
Clone this wiki locally