Skip to content

Migrate Jetsnack to Navigation 3#1647

Open
dturner wants to merge 7 commits intomainfrom
dt/jetsnack-nav3-migration
Open

Migrate Jetsnack to Navigation 3#1647
dturner wants to merge 7 commits intomainfrom
dt/jetsnack-nav3-migration

Conversation

@dturner
Copy link
Collaborator

@dturner dturner commented Feb 13, 2026

I have migrated Jetsnack to use Navigation 3.

Previously Jetsnack was using nested NavHosts. The outer NavHost held the Home and SnackDetail destinations and the Home destination had a NavHost containing the Feed, Search, Cart and Profile destinations. The Home destinations were all wrapped with a scaffold that displayed the bottom navigation bar. The SnackDetail destination was full screen without the bottom navigation bar.

I have refactored this to use a single back stack and a single NavDisplay is used for all screens. This simplifies the code, but does introduce a caveat.

In order to display the bottom navigation bar on the Home destinations the NavDisplay is wrapped with the scaffold. This means that the bottom bar is conditionally hidden when the SnackDetail navigation key is the last item in the back stack. This isn't particularly scalable. This may be better implemented as a scene decorator, although we're still figuring out best practices there.

Still to do:

  • When the moving between the Feed and Cart destinations the top bar disappears and reappears. It should stay put since it appears on both screens.
  • Shared element transitions between Cart and SnackDetail seem to be broken
  • Implement deeplinks.

Consider re-implementing this with nested NavDisplays.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @dturner, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request undertakes a significant refactoring of the Jetsnack application's navigation system by upgrading to Navigation 3. The core change involves transitioning from a complex nested NavHost setup to a more unified single back stack approach utilizing NavDisplay. This aims to simplify the overall navigation logic and state management, requiring adjustments to how UI elements, such as the bottom navigation bar, interact with the new navigation context.

Highlights

  • Navigation Framework Upgrade: The application has been migrated from the older Navigation Compose library to the new Navigation 3 framework.
  • Simplified Navigation Architecture: The previous architecture using nested NavHosts has been refactored to a single back stack managed by NavDisplay, streamlining navigation flow.
  • Type-Safe Navigation Keys: New NavKey data objects have been introduced for defining navigation destinations, enhancing type safety and clarity across the application.
  • Conditional Bottom Navigation Bar: The bottom navigation bar now conditionally hides when navigating to the SnackDetail screen, adapting to the single back stack model.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • Jetsnack/app/build.gradle.kts
    • Added Kotlin serialization plugin.
    • Removed androidx.navigation.compose dependency.
    • Added androidx.navigation3.ui, androidx.navigation3.runtime, androidx.lifecycle.viewmodel.navigation3, and kotlinx.serialization.json dependencies.
  • Jetsnack/app/src/main/java/com/example/jetsnack/ui/JetsnackApp.kt
    • Replaced AnimatedVisibilityScope with AnimatedVisibility and togetherWith for transitions.
    • Removed NavHost and rememberJetsnackNavController.
    • Introduced rememberNavBackStack and NavDisplay for navigation management.
    • Refactored MainContainer logic directly into JetsnackApp.
    • Implemented conditional display of JetsnackBottomBar based on SnackDetailKey.
    • Updated navigation calls to use NavBackStack methods and NavKeys.
    • Removed LocalNavAnimatedVisibilityScope.
  • Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt
    • Imported AnimatedContent and LocalNavAnimatedContentScope.
    • Replaced LocalNavAnimatedVisibilityScope with LocalNavAnimatedContentScope in SnackItem and HighlightSnackItem.
    • Updated JetsnackPreviewWrapper to use AnimatedContent and LocalNavAnimatedContentScope.
  • Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/DestinationBar.kt
    • Imported LocalNavAnimatedContentScope.
    • Replaced LocalNavAnimatedVisibilityScope with LocalNavAnimatedContentScope.
  • Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/Home.kt
    • Removed composableWithCompositionLocal and addHomeGraph functions.
    • Updated HomeSections enum to use NavKey objects instead of string routes.
    • Modified JetsnackBottomBar to accept NavKey for currentKey and an onItemClick callback.
  • Jetsnack/app/src/main/java/com/example/jetsnack/ui/navigation/JetsnackNavController.kt
    • Removed the custom navigation controller file, as its functionality is now handled by Navigation 3's NavBackStack.
  • Jetsnack/app/src/main/java/com/example/jetsnack/ui/navigation/NavKeys.kt
    • Added new file defining serializable NavKey data objects for FeedKey, SearchKey, CartKey, ProfileKey, and SnackDetailKey.
    • Added extension functions addHomeSection and addSnackDetail for NavBackStack<NavKey> management.
  • Jetsnack/app/src/main/java/com/example/jetsnack/ui/snackdetail/SnackDetail.kt
    • Imported LocalNavAnimatedContentScope.
    • Replaced LocalNavAnimatedVisibilityScope with LocalNavAnimatedContentScope in various composables within the snack detail screen.
  • Jetsnack/gradle/libs.versions.toml
    • Updated androidx-navigation version to androidx-navigation3.
    • Added androidx-lifecycle-navigation3 version.
    • Removed androidx-navigation-compose, androidx-navigation-fragment, androidx-navigation-ui-ktx library definitions.
    • Added androidx-navigation3-runtime, androidx-navigation3-ui, and androidx-lifecycle-viewmodel-navigation3 library definitions.
    • Added navigation3 version definition.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is a great migration to Navigation 3. It significantly simplifies the navigation structure by moving from nested NavHosts to a single back stack, which is much cleaner. The use of serializable NavKeys and NavDisplay is well-executed.

I've added a few comments, mostly focusing on ensuring runtime safety by restoring some null checks for navigation scopes that were removed during the refactoring. This will prevent potential NullPointerExceptions. I also included a suggestion to improve the 'clunky' logic for the bottom bar that you mentioned in your description, addressing both performance and redundant navigation triggers.

Overall, excellent work on this refactor!

)
}
},
transitionSpec = { transitionSpec },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why, but comparing between develop + this branch, the transition between the Feed and Cart composables looks a bit quicker, and doesn't seem like its performing a fadeIn or fadeOut. Doesn't look bad, I'm just wondering if there was a change missed here.
Not blocking on this one :)

Copy link
Collaborator

@riggaroo riggaroo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looking good! Just the bottom bar animation needs fixing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants