-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Migrate project to Jetpack Navigation 3 #2003
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Source code is still left in api module. impl module is empty at this point.
Bump agp versions and add navigation 3 dependency
Made NiaNavigator a stateless class only responsibly for navigating and pop (modifying backStack). Navigation state now lives in a new class called NiaNavigatorState. The state of this class is saved and restored by ViewModel.
This commit refactors the navigation state management by renaming `NiaNavigatorState` to `NavigationState` to make it more generic. Specific changes include: - Renamed `NiaNavigatorState` to `NavigationState`. - Renamed `NiaNavigatorProvider` to `NavigationStateProvider`. - Updated all usages of the renamed classes, including `NiaNavigator`, `NiaBackStackViewModel`, and various tests. - Replaced the `getEntries()` extension function with `toEntries()`. - Added numerous TODOs to identify areas for future improvement, such as removing dependencies on `SavedStateHandle` for navigation state, simplifying event handling in ViewModels, and documenting the new navigation components.
This commit refactors the navigation implementation by renaming all `...Route` classes to `...NavKey`. This change provides more descriptive and consistent naming for navigation keys across the codebase. Key changes include: * Renamed `BookmarksRoute` to `BookmarksNavKey` * Renamed `ForYouRoute` to `ForYouNavKey` * Renamed `InterestsRoute` to `InterestsNavKey` * Renamed `TopicRoute` to `TopicNavKey` * Renamed `SearchRoute` to `SearchNavKey` * Updated all associated feature modules, tests, and UI components to use the new `NavKey` names. * Removed obsolete test utilities and mock providers related to the old navigation setup. * Deleted outdated dependency graph images and their corresponding `README.md` files from feature modules.
Adds automatically generated dependency graphs to the README.md files for the following feature modules: - `:feature:bookmarks:api` - `:feature:bookmarks:impl` - `:feature:foryou:api` - `:feature:foryou:impl`
The `NiaAppStateTest` is updated to align with the changes in `InterestsNavKey`, which now requires a `topicId` argument. The test now uses `InterestsNavKey(null)` to correctly represent the top-level interests destination.
The `feature:settings:api` module has been renamed to `feature:settings:impl` to better reflect its role as an implementation module. This change includes: * Updating module paths and namespaces. * Moving all related files, including source code, resources, and tests, to the new `impl` directory. * Updating dependencies and project configurations in Gradle scripts and README files to point to the new module path. * Renaming string resources to include the `_impl` suffix for clarity. * Updating the AndroidX Lifecycle dependency to version 2.10.0.
|
@SimonMarquis I'm running into an issue where the Any idea what could be causing that? Additionally, when I run |
The string resource identifiers for settings have been updated in the navigation tests. The `feature_settings` prefix has been changed to `feature_settings_impl` to reflect changes in the settings feature module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Android Lint found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
This commit updates the `targetSdkVersion` and `compileSdkVersion` from 35 to 36.
|
@dturner the same commands seems to work as expected when I checkout eae7a5b on a GitHub Codespace, so I'm not sure what really happens. Also, I'd just like to point out that currently, the Graph generation does not support multiple nested groups nowinandroid/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Graph.kt Line 190 in d438a00
And this makes the ":feature" group disappear as you can see in ---
config:
layout: elk
elk:
nodePlacementStrategy: SIMPLE
---
graph TB
subgraph :core
direction TB
:core:analytics[analytics]:::android-library
:core:common[common]:::jvm-library
:core:data[data]:::android-library
:core:database[database]:::android-library
:core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library
:core:designsystem[designsystem]:::android-library
:core:model[model]:::jvm-library
:core:navigation[navigation]:::android-library
:core:network[network]:::android-library
:core:notifications[notifications]:::android-library
:core:ui[ui]:::android-library
end
subgraph :feature:bookmarks
direction TB
:feature:bookmarks:api[api]:::android-library
:feature:bookmarks:impl[impl]:::android-library
end
subgraph :feature:topic
direction TB
:feature:topic:api[api]:::android-library
end
:core:data -.-> :core:analytics
:core:data --> :core:common
:core:data --> :core:database
:core:data --> :core:datastore
:core:data --> :core:network
:core:data -.-> :core:notifications
:core:database --> :core:model
:core:datastore -.-> :core:common
:core:datastore --> :core:datastore-proto
:core:datastore --> :core:model
:core:network --> :core:common
:core:network --> :core:model
:core:notifications -.-> :core:common
:core:notifications --> :core:model
:core:ui --> :core:analytics
:core:ui --> :core:designsystem
:core:ui --> :core:model
:feature:bookmarks:api --> :core:navigation
:feature:bookmarks:impl -.-> :core:data
:feature:bookmarks:impl -.-> :core:designsystem
:feature:bookmarks:impl -.-> :core:ui
:feature:bookmarks:impl -.-> :feature:bookmarks:api
:feature:bookmarks:impl -.-> :feature:topic:api
:feature:topic:api -.-> :core:designsystem
:feature:topic:api --> :core:navigation
:feature:topic:api -.-> :core:ui
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
|
Updated string resource identifiers in the `SettingsDialogTest` to follow the `feature_settings_impl_` prefix convention. This aligns the test resources with the recent module renaming.
|
I don't have much time to dedicate to adding support for nested projects right now, but maybe this could be a good fit for a vibe coding task 🤓 |
|
@SimonMarquis Thanks for the quick response. No worries, I'll see what Gemini can do... |
...navigation/src/main/kotlin/com/google/samples/apps/nowinandroid/core/navigation/Navigator.kt
Outdated
Show resolved
Hide resolved
...tion/src/main/kotlin/com/google/samples/apps/nowinandroid/core/navigation/NavigationState.kt
Show resolved
Hide resolved
Renamed the `goUp` method to `clearSubStack` to more accurately reflect that its function is to clear the sub-stack.
Add `rememberViewModelStoreNavEntryDecorator` to the list of decorators for `NavEntry` instances. This enables support for `ViewModel` instances within the navigation component.
This PR migrates the project from using Navigation Compose (aka Nav2) to Navigation 3. It follows the official migration guide.
Implementation details
Navigable content
Every piece of navigable content in the app is represented by a navigation key. These are objects that implement the
NavKeyinterface. Each feature has anapimodule which defines these navigation keys.Example from the
:foryou:apimodule:The content itself is defined using extension functions on
EntryProviderScope<NavKey>. These extension functions are defined by each feature in itsimplmodule.Example from the
:foryou:implmodule:The app (specifically the
NiaAppcomposable) calls these extension functions directly to create anentryProvider. This is used to resolve the navigation keys toNavEntrys which contain the navigable content:Modeling state
Navigation state is held using the
NavigationStateclass and scoped toNiaApp. This is a state holder, it does not create its own state. The navigation state - a top level back stack and sub stacks for each top level key - is created usingrememberNavigationState. This uses Nav3'srememberNavBackStackhelper function to allow that state to persist config changes and process death.Handling navigation events
Navigation events -
navigateandgoBack- are handled using theNavigatorclass. This modifies theNavigationStatein response to these events. TheNavigatoris also scoped toNiaAppand passed directly to each feature'sEntryProviderScopeextension functions so that the content can trigger navigation events.Updating the UI
NavigationStatehas an extension functiontoEntriesthat uses theentryProviderto convert its state intoNavEntrys. These are then displayed using aNavDisplayinside theNiaAppcomposable. Any changes to the navigation state will causeNavDisplayto recompose and update its UI.Notably,
toEntriescallsrememberDecoratedNavEntriesfor each sub stack. This allows the state of each sub stack to be retained, even when that sub stack isn't in the current stack being displayed byNavDisplay. This is so that when you tap on a previously visited top level destination, the state of all those screens is retained.Summary of data flow
NavigatorNavigatorchangesNavigatorStateNavigatorState.toEntriesrecomposes, recreating the list ofNavEntrysNavDisplayrecomposes, displaying thoseNavEntrysNotable points
This PR builds on the work done by @claraf3 in #1902