Conditional Navigation in Jetpack Compose

The sample app

Main screens

Navigation

Ancillary classes

  • OnboardingState which will represent whether the user has already completed the onboarding flow.
  • OnboardingResult which indicates, once we have navigated to the Onboarding screen, whether the user completed onboarding, or cancelled the flow.
  • A storage mechanism to persist the onboarding state. The implementation for this story is an in-memory storage solution, it is not persisted — in a production app this would be persisted using data store or shared preferences. This storage solution exposes the current onboarding state as a flow, so that it can be observed.

Navigating to Onboarding

  1. First we update our Home node in the navigation graph to pass to the HomeRoute a reference to our storage class, and a lambda to call in order to navigate to the Onboarding Screen.
  2. We define a HomeRoute composable that wraps the HomeScreen, and accepts the OnboardingStorage class.
  3. Our HomeRoute also takes a lambda to navigate to Onboarding.
  4. In the HomeRoute we observe the onboarding state from the OnboardingStorage class.
  5. Based on the onboarding state, we will do a couple of different things.
  6. If the user has not onboarded, we navigate to Onboarding.
  7. Note that navigating to Onboarding is within a LaunchedEffect — this is important because any side effects, i.e., actions not directly related to composition, should not be done during the composition flow, but as part of a side effect, in this case we use LaunchedEffect because we want to this just once.
  8. If the user has Onboarded, then we display the Home screen content.

Handling onboarding result

  • When we launch the app, we will check in the Home screen if we need to show onboarding.
  • If we do, then we will check the SavedStateHandle for a result from the onboarding screen. This value will initially be null as it has not been populated yet, in which case we will navigate to the Onboarding screen. If the value is not null, then it could be OnboardingComplete or OnboardingCancelled. If it is OnboardingComplete, we will show the home content and, if it is OnboardingCancelled, we will close the app.
  • In the Onboarding screen, when it first launches, we will set the Onboarding result as OnboardingCancelled — that will cover the case of the user exiting the screen via the back button and returning to Home. Once the user has completed the onboarding flow, we will set the onboarding result as OnboardingCompleted and pop the back stack, to return to Home.
  • When we return to the Home screen, we will retrieve the onboarding result from the SavedStateHandle and either show the main content or exit the app.
  1. In our Home Route we provide the Storage class to observe the onboarding state.
  2. We also provide the SavedStateHandle to retrieve the result from the Onboarding screen.
  3. We pass a lambda to navigate to the Onboarding screen.
  4. And also we pass a lambda to finish the app.
  5. On the Onboarding node we first initialize the previous back stack entry’s SavedStateHandle (belonging to the Home navigation graph node) with a result of OnboardingResult.Cancelled, this way if the user leaves the Onboarding screen this will be the default value read when returning to the Home screen.
  6. We also provide a lambda to pop the backstack, for when the user has completed onboarding.
  1. We observe the onboarding result from the SavedStateHandle that we receive as argument.
  2. If the user has not been shown onboarding yet, we check the onboarding result.
  3. If it is null it means it is a fresh app launch, so we navigate the user to the Onboarding screen.
  4. If the value is Completed then the Onboarding flow was completed successfully and we show the main content. This should not be hit because we are setting the onboarding state to completed in the onboarding screen, so when returning to home we fall to the OnboardingState.Onboarded clause, but it is added here for completeness sake.
  5. Finally, if the value is Cancelled it means the user cancelled the onboarding flow and we call the lambda to exit the app.
  1. The Onboarding screen takes the onboarding storage, to update the state, and a lambda to pop the back stack.
  2. When we display the onboarding content we provide a callback for when onboarding has completed.
  3. In this callback we update our storage to persist that the user has completed the onboarding flow.
  4. And use the lambda to pop the back stack and return to the Home screen.

Conclusion

--

--

--

Senior Android Developer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Java Faker library to generate fake data.

Removing orphan records from Azure App Configuration Service when importing the data

Learning To Code At A Product Focused School

Hosting a Static Website on Azure with Pulumi

My Journey into Coding

Build your own URL Shortener in 2 hours or less!

Working of our custom URL Shortener service

Week #9–7125GFS CGI: Character Modelling

Scala Snippets #1: Instanitable Implicits

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Francesc Vilarino Guell

Francesc Vilarino Guell

Senior Android Developer

More from Medium

Exploring Jetpack Compose LazyList animations

Bottom Navigation Jetpack Compose.

Jetpack Compose Logo

Navigation in Jetpack Compose Android

Jetpack Compose Power Navigation