Releases: raamcosta/compose-destinations
1.4.4-beta - Support for Ktx Serialization as navigation argument types
Changes
Bumped Compose Navigation version to 2.4.2. This fixes #85! 🎉
New Features
- Types annotated with
@Serializable
from Kotlinx Serialization can now be used as navigation arguments out of the box. (thanks @rafaeltonholo 🙌)
This closes #51!
They now work similarly to Parcelable/Serializable types.
Bug fixes
- Fixes issue with the custom navigation type feature. It was not working if your string had special characters.
Read about the feature here
1.4.3-beta - WRONG BUILD - USE 1.4.4-beta
1.4.3-beta
1.4.2-beta
Changes
#84 Fix
With 1.4.0-beta a change to the NavType generation templates was mistakenly done. This was impacting out of the box Serializable / Parcelable navigation arguments as the generated code was not compiling.
1.4.1-beta
Changes
1. Fixed issue when a result was sent back from a dialog to another dialog
Feature described here
2. Housekeeping refactors
I had some time and figured I wanted to check public APIs and packages since some code started as part of specific features but since evolved to be more general. So, I apologize for these breaking changes, but I wanted to do them now rather than later. I have used deprecation before to avoid doing this, but in this case, the trouble was too big and the changes have a very easy fix OR are from a very niche feature.
-As part of this houskeeping we moved a couple of functions from com.ramcosta.composedestinations.manualcomposablecalls
to com.ramcosta.composedestinations.scope
. So if you have some red imports, delete them and re-import.
-We were able to change the visibility of some internal APIs to internal
. If you find you cannot call something you could before and if you think you really need to, please open an issue so I can help you find the right API.
-Improvements on vanilla NavHosts usage. Support described here
If you were not using this specific support, you can ignore these.
Click to expand details
These improvements did change NavHost extension function APIs to bring them more in line with what we do when manually calling the Composables and to make the arguments available more scalable in the future while easily keeping compatibility with older versions. The navigation arguments will be lazily evaluated (like they are everywhere else).
Notice how we get navigation arguments, and the other parameters to pass to the Screen Composable before and after.
- Before
NavHost(
// ...
) {
composable(SomeScreenDestination) { args, navBackStackEntry ->
SomeScreen(
arg1 = args.arg1,
arg2 = args.arg2,
navigator = DestinationsNavController(navController, navBackStackEntry),
resultRecipient = resultRecipient(navBackStackEntry),
resultNavigator = resultBackNavigator(
navController = navController,
destinationSpec = SomeScreenDestination
)
)
}
}
- After:
NavHost(
// ...
) {
composable(SomeScreenDestination) { // this: NavGraphBuilderDestinationScope<SomeScreenDestination.NavArgs>
SomeScreen(
arg1 = navArgs.arg1,
arg2 = navArgs.arg2,
navigator = destinationsNavigator(navController),
resultRecipient = resultRecipient(),
resultBackNavigator = resultBackNavigator(navController)
)
}
}
1.4.0-beta - Custom Navigation Types support
Changes
-
Support to make any type navigation argument type! (thanks @rafaeltonholo 🙌 ).
This enables you to, with some setup, pass any type you want via navigation argument, even if they're not Parcelable/Serializable.
Read about this feature here- While developing this feature, we noticed we could also simplify
@NavTypeSerializer
annotated classes for when the type is Parcelable/Serializable. So in the rare occasion you were using this feature before, simply replaceParcelableNavTypeSerializer
andSerializableNavTypeSerializer
withDestinationsNavTypeSerializer
(we now have a unique interface for all types).
- While developing this feature, we noticed we could also simplify
-
Added
popUpTo
extension function toNavOptionsBuilder
that receives aRoute
. This makes it more in line with other Compose Destinations APIs, and is the recommended way to define the route you want to pop up to when navigating.
1.3.5-beta - Back Result feature improvement
Changes
- Fixed #69 :
ResultRecipient
now has aonNavResult
method that replaces the now deprecatedonResult
method. It now wraps the result in aNavResult
which can be eitherCanceled
if the result sender screen doesn't set a result before being dismissed, or aValue
with the actual result if it was set.
This way you can now react to if the result sender screen is canceled without sending an actual result back.
1.3.4-beta
Changes
- Fixed #68: ResultRecipient issue with DynamicDestinationSpec originators
1.3.3-beta
Changes
-
Make
dependenciesContainerBuilder
@Composable
(thank you @nrobi144! 👏 )
This allows you to call Composable functions to create dependencies in the lambda you want to provide to your screens -
Updated accompanist dependency
1.3.2-beta
Changes
- Fixed #60 : Parcelable interfaces types used as navigation arguments now work as expected.
- Improved a reported case of being unable to get package name for generated files by failing ksp task and suggesting manual package name by
build.gradle
config.
1.3.1-beta - Multi module configurations 🙌
CHANGES
New multi-module configurations
ksp {
arg("compose-destinations.mode", "[YOUR_MODULE_MODE]") // can be "destinations", "navgraphs" or "singlemodule" (default)
arg("compose-destinations.moduleName", "featureA")
}
Read details here
For multi-module apps, you can now use the above two configs in each module's `build.gradle` where you are going to use Compose Destinations `ksp` dependency (in other words where you will annotate composables with `@Destination`). `YOUR_MODULE_MODE` can be replaced with:-
"destinations"
:
The module will generate the destinations of the module and exposes a list with all of them. Doesn't generate any nav graphs. The nav graphs should then be manually built in the "navigation module" where you call theDestinationsNavHost
.
This is useful if your module wants to expose a single or multiple destinations but they should belong to a navigation graph that also contains destinations from other modules. (Example of usage: Chris Banes tivi project - https://github.com/raamcosta/tivi) -
"navgraphs"
:
The module will generate nav graph (or graphs if you usenavGraph
on some destination annotations) and its destinations.
This should be used if your module generates one or multiple navigation graphs that will then be consumed in other module, usually the "navigation module" that callsDestinationsNavHost
. (Example of usage: Philipp Lackner project -https://github.com/raamcosta/CalorieTracker) -
"singlemodule"
(default if none is specified):
The default mode that was applied until now always. It generates aNavGraphs
object will all nav graphs inside and it nests all of them inside the "root" one. It is also the only mode that generates aCoreExtensions.kt
file (this is basically a file with utilities that you can always create yourself if you need to. Main purpose is utilities that use the generatedNavGraphs.root
and expose the (generated) sealed version of aDestination
instead of theDestinationSpec
fromt he core module).
DestinationsNavigator navigate method will now navigate even if the screen you are navigating from is not in the RESUMED state.
This method has a onlyIfResumed
parameter and until now it was true by default.
This change shouldn't be noticeable in 90% of cases, but if you notice a case where before you were safe from multi clicks and now you are not, then specify onlyIfResumed = true
.
Reason for the change
The truth is that this was a complete overshight on my part. I thought I'd be helping by avoiding double clicks and similar cases with this flag as true by default, but in reality if a method is called `navigate` and by default it can just "fail" silently, it can be a very awkward situation. This way, if you explicitly pass `onlyIfResumed = true`, it means you read the documentation and if in your flow for some reason you want to navigate while not in the RESUMED state, then you already know why it fails. Besides, every single report I have of "the navigate method is not working" I suddently have to think about this possibility. Another reason is that this way we have the same behaviour of `NavController.navigate` method by default. In the end, if you have specific cases where you want to avoid double navigation calls, just pass `onlyIfResumed = true`.Dynamic destinations - DynamicDestinationSpec
Allows the same Destination to be used in multiple Navigation Graphs.
Read more
Until now, 1 Annotated Composable = 1 Generated Destination = 1 Route in the navigation graph. With tivi project, the approach of Chris Banes was something I actually had never seen before. The same destination Composable is used in multiple navigation graphs and for each, it has a different actual route. So to make this possible, you can use YourScreenDestination routedIn YourNavGraph
and YourScreenDestination routedIn AnotherNavGraph
when building the NavGraphs
. Each of these routedIn
calls will return differently routed DynamicDestinationSpecs
that are exactly the same as YourScreenDestination
except that it has a different route (in practice it is navGraphRoute/destinationRoute
.
When navigating to these Destinations, you have to do: navigator.navigate(YourScreenDestination(yourNavArgs) within YourNavGraph)
.
Check this for an example: https://github.com/raamcosta/tivi/blob/main/app/src/main/java/app/tivi/AppNavigation.kt
DependenciesContainerBuilder
It is a DestinationsNavHost
parameter that allows you to define certain components as dependencies that will be available to all or some annotated Composables. This is especially useful if you have some components that you want to make available for all screens or most. If you have a specific screen that needs a specific component, then you can still opt to manually call it with manualComposableCallsBuilder
.
Enhancement #53
You can now setResult
and navigate back with different calls of ResultBackNavigator
.
Small changes:
- Internal Compose related versions bumped to 1.1.0 Stable
DestinationSpec
now has arouteId
which is the route without navigation arguments information.DestinationSpec.Content
Composable method is now extension onDestinationScope
(which was only used in theManualComposableCallsBuilder
) instead of receiving NavController and NavBackStackEntry, which can be retrieved via that scope.DestinationScope
now has theDestination
instance which can be helpful in thedependenciesContainerBuilder
parameter to know whcih destination is being navigated to and offer or not some dependencies depending on that.