-
Notifications
You must be signed in to change notification settings - Fork 267
update: details on Navigation 3 implementation available in CMP 1.10 #591
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
Open
zamulla
wants to merge
8
commits into
master
Choose a base branch
from
zamulla/cmp-navigation-3
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 5 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b0f54f0
update: initial nav3 draft
zamulla 0ade7d3
update: style tag
zamulla 66b6d1a
update: style tag
zamulla 447fe76
update: a couple of comments
zamulla b391c12
update: structure and what's next
zamulla bdc0b01
fix: SME review
zamulla e154941
fix: SME review
zamulla da1aa45
fix: SME review
zamulla File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| [//]: # (title: Navigation 3 in Compose Multiplatform) | ||
| <primary-label ref="alpha"/> | ||
|
|
||
| [Android's Navigation library](https://developer.android.com/guide/navigation) is upgraded to Navigation 3, a redesigned approach to navigation that works with | ||
| Compose and takes into account feedback to the previous version of the library. | ||
| Starting with the version 1.10, Compose Multiplatform helps adopt Navigation 3 into multiplatform projects. | ||
|
|
||
| ## General overview | ||
|
|
||
| Navigation 3 is more than a new version of the library — in a lot of ways it's a new library entirely. | ||
| To dive deeper into the philosophy behind it, see the [Android Developers blog post](https://android-developers.googleblog.com/2025/05/announcing-jetpack-navigation-3-for-compose.html). | ||
|
|
||
| The major changes in the new library are: | ||
|
|
||
| * **User-owned back stack**. Instead of operating a single library back stack, | ||
| you create and manage a `SnapshotStateList` of states which is observed by the UI. | ||
| * **Low-level building blocks**. Thanks to closer integration with Compose, the library allows more flexibility | ||
| in implementing your own navigation components and behavior. | ||
| * **Adaptive layout system** that allows to display multiple destinations at the same time and seamlessly switch between layouts. | ||
|
|
||
| Learn more about general design of Navigation 3 in [Android documentation](https://developer.android.com/guide/navigation/navigation-3). | ||
|
|
||
| ## Dependencies setup | ||
|
|
||
| To try out the multiplatform implementation of Navigation 3, add the following dependency to your version catalog: | ||
|
|
||
| ```text | ||
| [versions] | ||
| compose-multiplatform-navigation3 = "1.0.0-alpha05" | ||
|
|
||
| [libraries] | ||
| jetbrains-navigation3-ui = { module = "org.jetbrains.androidx.navigation3:navigation3-ui", version.ref = "compose-multiplatform-navigation3" } | ||
| ``` | ||
|
|
||
| > While Navigation 3 is released as two artifacts, `navigation3:navigation3-ui` and `navigation3:navigation3-common`, | ||
| > only `navigation-ui` needs a separate Compose Multiplatform implementation. | ||
| > A dependency on `navigation3-common` is added implicitly. | ||
|
||
| > | ||
| {style="note"} | ||
|
|
||
| Additional support for Navigation 3 is implemented in Material 3 Adaptive and ViewModel. | ||
| If you're using these libraries, add the navigation support artifacts as well: | ||
| ```text | ||
| [versions] | ||
| compose-multiplatform-adaptive = "1.3.0-alpha02" | ||
| compose-multiplatform-lifecycle = "2.10.0-alpha05" | ||
|
|
||
| [libraries] | ||
| jetbrains-material3-adaptiveNavigation3 = { module = "org.jetbrains.compose.material3.adaptive:adaptive-navigation3", version.ref = "compose-multiplatform-adaptive" } | ||
| jetbrains-lifecycle-viewmodelNavigation3 = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-navigation3", version.ref = "compose-multiplatform-lifecycle" } | ||
| ``` | ||
|
|
||
| Finally, you can try out the [proof-of-concept library](https://github.com/terrakok/navigation3-browser) | ||
| authored by a JetBrains engineer that adds support for Navigation 3 to web targets: | ||
|
||
|
|
||
| ```text | ||
| [versions] | ||
| compose-multiplatform-navigation3-browser = "0.2.0" | ||
|
|
||
| [libraries] | ||
| navigation3-browser = { module = "com.github.terrakok:navigation3-browser", version.ref = "compose-multiplatform-navigation3-browser" } | ||
| ``` | ||
|
|
||
| > Web support is expected to be added to the base multiplatform Navigation 3 library in version 1.1.0. | ||
| > | ||
| {style="note"} | ||
|
|
||
| ## Multiplatform support | ||
|
|
||
| Navigation 3 is closely aligned with Compose and therefore a navigation implementation written for Android works in common | ||
| Compose Multiplatform code almost without changes. | ||
| The only thing you need to add to support non-JVM platforms like web and iOS is implement | ||
| [polymorphic serialization for destination keys](#polymorphic-serialization-for-destination-keys). | ||
|
|
||
| You can compare extensive examples of Android-only and multiplatform apps using Navigation 3 on GitHub: | ||
| * [original Android repository with Navigation 3 recipes](https://github.com/android/nav3-recipes) | ||
| * [Compose Multiplatform project with most of the same recipes](https://github.com/terrakok/nav3-recipes) | ||
|
|
||
| ### Polymorphic serialization for destination keys | ||
|
|
||
| On Android, Navigation 3 relies on reflection-based serialization, which is not available when you target non-JVM platforms like iOS. | ||
| To take this into account, the library has two overloads for the `rememberNavBackStack()` function: | ||
|
|
||
| * [The first overload](https://developer.android.com/reference/kotlin/androidx/navigation3/runtime/package-summary#rememberNavBackStack(kotlin.Array)) | ||
| only takes a set of `NavKey` and requires a reflection-based serializer. | ||
| * [The second overload](https://developer.android.com/reference/kotlin/androidx/navigation3/runtime/package-summary#rememberNavBackStack(androidx.savedstate.serialization.SavedStateConfiguration,kotlin.Array)) | ||
| also takes a `SavedStateConfiguration` parameter that allows you to provide a `SerializersModule` and handle open polymorphism | ||
| correctly across all platforms. | ||
|
|
||
| In the multiplatform examples of Navigation 3 it can look [like this](https://github.com/terrakok/nav3-recipes/blob/8ff455499877225b638d5fcd82b232834f819422/sharedUI/src/commonMain/kotlin/com/example/nav3recipes/basicdsl/BasicDslActivity.kt#L40): | ||
|
|
||
| ```kotlin | ||
| @Serializable | ||
| private data object RouteA : NavKey | ||
|
|
||
| @Serializable | ||
| private data class RouteB(val id: String) : NavKey | ||
|
|
||
| // Creates the required serializing configuration for open polymorphism | ||
| private val config = SavedStateConfiguration { | ||
| serializersModule = SerializersModule { | ||
| polymorphic(NavKey::class) { | ||
| subclass(RouteA::class, RouteA.serializer()) | ||
| subclass(RouteB::class, RouteB.serializer()) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @Composable | ||
| fun BasicDslActivity() { | ||
| // Consumes the serializing configuration | ||
| val backStack = rememberNavBackStack(config, RouteA) | ||
|
|
||
| NavDisplay( | ||
| backStack = backStack, | ||
| //... | ||
| ) | ||
| } | ||
| ``` | ||
|
|
||
| ## What's next | ||
|
|
||
| Navigation 3 is covered in-depth on the Android Developer portal. | ||
| Sometimes this documentation uses Android-only examples, | ||
| but fundamental guidance and navigation principles are the same for Multiplatform: | ||
|
|
||
| * [Overview of Navigation 3](https://developer.android.com/guide/navigation/navigation-3) | ||
| with advice on managing state, modularizing navigation code, and animation. | ||
| * [Migration from Navigation 2 to Navigation 3](https://developer.android.com/guide/navigation/navigation-3/migration-guide). | ||
| It's easier to see Navigation 3 as a new library than a new version of the existing library, | ||
| so it's less of a migration and more of a rewrite. | ||
| But the guide points out the general steps to take. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
I would name it just
multiplatform-nav3andmultiplatform-nav3-ui