Appyx vs Jetpack Compose Navigation
The Bumble team has just recently released a navigation framework: Appyx
See the intro article here:
Appyx is released! (1.0-alpha02)
A modern, clean approach to structuring your Android application
Appyx is a fundamentally different approach compared to how you would do things with Jetpack Compose Navigation!
In this article, we’ll focus on a few use-cases and compare them in practice.
Use-case I — Simple navigation case
Let’s take a look at this simple navigation example where we navigate from Home screen to Search screen:
This approach has a few drawbacks:
- String based arguments which need to form a valid route. Developers are responsible for managing all routes themselves. They need to keep in mind what arguments are required by a particular screen, as well as keys, data types, and their order.
They must not forget to update code manually whenever something changes, as route validation happens only at runtime and can result in unexpected crashes.
- Separation of concerns. Navigation comes from the “view” layer instead of business logic. This means that we have to define our UI implementation next to navigation.
- Testability. Because our navigation is defined in the composition, we can’t simply unit-test.
Let’s take a look at how we can do it with Appyx. First, let’s define our navigation targets with classes:
Then implement UI for your navigation targets in a
Then we define how those NavTargets relate to Nodes, and where to draw them in the Composable UI:
To navigate to the Search screen simply add an appropriate NavTarget to
This approach addresses the problems mentioned above:
- NavTargets. Your navigation targets are defined as classes so that you have compiled time checks for your arguments.
- Navigation is separated from the UI.
BackStackis a Kotlin class so to test your navigation you just need to verify that
BackStackis in the correct state.
As a bonus — it’s also recomposition safe. Only the View method is a composable function, the
Node itself is not. So, it’s safe to provide/inject your dependencies without worrying about recomposition.
Use-case II — Transition animations
But this also has drawbacks:
- Internally, the navigation library internally always uses
BackStack. Therefore, only enterTransition, exitTransition, popEnterTransition, popExitTransition are available. Further customisations are not possible. We’ll see use-cases for this later in this article.
- For animation you can only use properties defined in
This Appyx example animates colour and rotation. It would not be possible to achieve this with
In Appyx transition animations can be added with a one-liner:
Let’s take a look under the hood at the
- Transitions are defined in a separate class, so keep your main composables cleaner.
- TransitionHandler returns a
Modifierwhich will be applied to a child
Nodecomposable. This is extremely powerful — properties like colour and rotation are just the start. You can use anything and everything that can be animated with a
- Transitions are not limited to the enterTransition, exitTransition, popEnterTransition, popExitTransition used in Jetpack Compose Navigation’s BackStack. We can define custom animations for any back stack operation (e.g. replace, new root, single top, etc.), or between any two back stack states.
Use-case III— No alternative to a back stack
So far in both Jetpack Navigation and Appyx we used
BackStack as a navigation engine.
But this is not always what we need! For instance, we may want to switch back and forth between navigation targets without re-creating UI — like a ViewPager:
Unfortunately, this is not possible with Jetpack Compose Navigation as it internally uses solely
Instead of a hardcoded
BackStack Appyx provides an abstraction
BackStack is just one of many possible implementations, and to achieve ViewPager-like navigation we just need to implement a different navigation model.
Navigation models provide the ability to implement anything you can think of, easily. It might be an enhanced ViewPager like this one which allows us to switch between pager and carousel modes:
This one is also animated using a TransitionHandler like we did for our back stack — as you can see, it’s a much more versatile approach with a lot more freedom compared to the fixed set of animations in Jetpack Compose Navigation.
How do you implement these more custom navigation models? We’ll return to this in another article and give a step-by-step explanation.
Want to know more about
NavModel right now? Check out our official documentation here.
I hope you found this article interesting, and that it will help you to look at navigation from a different angle! Let’s summarise the key features of Appyx when dealing with navigation in Jetpack Compose:
- Type-safe arguments for NavTargets and compile-time checks
- Navigation and UI are separated
- Navigation can be unit-tested
- Nodes are the perfect place to inject your dependencies without worrying about re-composition
- Powerful transitions that are not restricted by the
- Navigation models are not limited to
In the meantime:
- Check out the GitHub repo: https://github.com/bumble-tech/appyx
- Check out the project page: https://bumble-tech.github.io/appyx/
- Launch the :app module in the library for a hands-on demo and be inspired!