Navigating in Compose: Criteria

Navigating in Compose: Criteria

Navigating involving screens is a widespread act in an Android app… although, as
Zach Klippenstein noted,
“screen” is a fairly amorphous phrase. Normally, we want to be able to navigate
to different “screens” when people screens are carried out as composables.

How we do this is a really contentious matter.

About speaking, there looks to be four key categories of options:

  • Use the formal Jetpack Navigation for Compose

  • Use some type of wrapper or helper around Navigation for Compose —
    Rafael Costa’s compose-places library
    is an case in point

  • Use Jetpack Navigation, but use the “classic” implementation as a substitute of Navigation
    for Compose, making use of fragments to wrap your display screen-level composables

  • Use some independent navigation implementation, such as Adriel Café’s Voyager library

I are unable to tell you what to use. I can inform you that you need to appear up with a set
of requirements for judging different navigation answers. Dependent on a study of a bunch
of navigation methods, right here are some conditions that you may perhaps want to look at.

Desk Stakes

If your navigation solution does not assistance forward navigation to N destinations,
or if it does not assist again stacks (e.g., a goBack() function to pop a destination
off the stack and return to the place you had been before), use anything else.

Compile-Time Kind Safety

One particular crucial place of using Kotlin, and Java before it, is sort security. The additional type
security we get, the extra possible it is that we will uncover difficulties at compile-time,
instead than only through tests or by the application going 💥 for your users.

…For Routes/Locations

When you notify the navigation answer the place to navigate to in ahead navigation,
you may want to want answers where by the identifier is some thing that is variety secure.
Some answers use strings or integers to detect routes or locations. That helps make
it extremely easy to do some truly terrifying things, like compute a place working with math.
Typically, primitives-as-identifiers provide tiny compile-time defense. You may prefer
remedies that use enums, sealed class, marker interfaces, or other things that
recognize what are and are not legitimate solutions.

(and if you are inquiring oneself “what about deeplinks?”, that is protected a little bit later on)

…For Arguments

Usually, our screens need information, irrespective of whether an identifier (e.g., main critical) or
the real information alone. So, we want to be ready to pass that details from preceding
screens. All else remaining equal, you could possibly want to want alternatives that present compile-time
variety basic safety, so you do not wind up in cases where by you provide a string and the receiver
is expecting an Int alternatively.

A relevant criteria is “content safety”. You could possibly want to favor methods wherever your
code can just go the data, devoid of owning to worry about no matter whether it complies with
any remedy-unique limitations. For example, if the resolution calls for you to URL-encode
strings to be equipped to move them properly, that is not good, as you will overlook to do this from
time to time. Preferably, the resolution handles these types of points for you.

…For Return Values

At least for modal locations, this kind of as dialogs, we usually need to pass back some
form of “result”. For illustration, we show a dialog to allow for the consumer to pick a little something,
and we have to have the former screen to locate out what the person picked. Sometimes, there
are approaches of carrying out this outdoors of a navigation answer, these kinds of as the dialog
updating some shared data illustration (e.g., shared Jetpack ViewModel) exactly where
the preceding monitor finds out about results reactively. But, if the navigation resolution
you are looking at delivers return values, and you intend to use them, you may possibly want
to want types where individuals return values are also form-secure and written content-protected.

IOW, ahead-navigation arguments ought to not get all the security adore.

Help for Configuration Modify and Procedure Dying

Like it or not, configuration variations are actual. Birds, perhaps not.

A person way or a different, your application desires to be in a position to cope with configuration adjustments,
and your navigation resolution should really be equipped cope as very well, to guidance your application.
This involves each retaining the navigation data alone across configuration variations
and, preferably, obtaining a pattern for app knowledge for your screens to endure as perfectly
(e.g., Navigation for Compose’s for every-route ViewModel help).

Connected is method demise:

  • The user makes use of your application for a even though

  • The consumer will get distracted by some not-a-chicken for a though, and your app’s UI moves to the track record

  • When in the history, Android terminates your method to free of charge up method RAM

  • The user returns to your app soon after your system dies, but in a realistic period of time
    (last I understood, the restrict was 30 minutes, though that benefit may perhaps have transformed around the several years)

Android is heading to want to not only provide up your app, but pretend that your procedure
had been about all that time. That is the place “saved instance state” comes into play,
and ideally your navigation remedy advertises assist for this, so your back-stack
and so on get restored alongside with your UI.

Hooks For Stuff You May well Use

Only you know what your app is likely to want to do in terms of its UI. Or possibly
your designers know, or your product supervisors. Or, hey, maybe you are just spraying
pixels all over like Jackson Pollock sprayed paint.
Who am I to choose?

Irrespective, there might be some factors that you want in your app’s UI or stream that
tie into what you will need to have out of your navigation answer.

Quite a few apps use these types of UI constructs. It may possibly not be important that they be taken care of
by means of a navigation resolution — you could possibly be equipped to design them as getting “internal implementation”
of a screen, for case in point. But, it would be great to get a feeling of what designs
are established, if any, for a individual navigation option to tie into these
varieties of UI constructs. For illustration, if you need to have to capable to not only navigate to a display, but
to a specific tab or page inside of that display screen, it would be awesome if the navigation
option supported that. Perhaps not critical, but awesome.

And, for some of these UI constructs, you may be in search of to have multiple back stacks. For case in point,
you may want to have it so that back again navigation within just a tab normally takes you to former content
within that tab, somewhat than going again to other tabs that the person earlier visited.
Assist for several back again stacks appears to be to be a bit of an highly developed characteristic, so if this
is crucial to you, see what prospect navigation alternatives offer you.

Deeplinks are common. Listed here, by “deeplink”, I not only suggest scenarios where a vacation spot
is triggered from outdoors of the application, this kind of as from a connection on a Net web site. I also indicate
cases in which a location is identified at runtime based on details from an outdoors
supply, this sort of as a server-driven “tip of the day” card that steers end users to particular
screens within just the app.

If you imagine that you will want this kind of things, it will be valuable if your navigation
option supports them immediately. That assistance may possibly not be required — just as your
other app code can navigate to locations, your “oh, hey, I received a deeplink” code
can navigate to locations. However, a navigation resolution may perhaps simplify that,
specially for scenarios the place the deeplink is from outside of the app and you need
to determine what to do with the previously-operating app and its existing back stack.

When analyzing deeplink support, a person requirements that I will strongly advise is:
deeplinks should really be opt-in. Not every single display screen in your app need to be instantly
reachable by some outdoors occasion just by remaining tied into some navigation system
— that can lead to some safety challenges.

Also, think about how knowledge in the deeplink will get mapped to your arguments (at minimum
for routes that just take arguments). Some navigation remedies will attempt to take care of
that immediately for you, but be wary of options that use deeplinks as an justification
to be weak on variety safety. Ideally, there ought to be an unambiguous way to transform items
of a deeplink (e.g., path segments, question parameters) to navigation arguments, but
in a way that limitations any “stringly typed” logic to deeplinks by themselves and does not
break style security somewhere else.

Transitions

Your designers could possibly call for a specific way to changeover from display screen X to display
Y, such as a slide, a fade, a slide-and-fade, a fireworks-design explosion destroying
X with Y showing powering it, and so forth. Ideally, the navigation solution would manage
those kinds of transitions, specially if you have to have to control the back again-navigation
changeover as well (e.g., the exploded fireworks by some means reassembling on their own into a monitor,
since that sounds like exciting).

Advancement Things to consider

Does the library have crystal clear documentation? Does it appear to be taken care of? Does it
have a obvious way of finding assistance? Does it have a license that is compatible with
your venture? These are all typical requirements for any library, and navigation answers
are no exception.

Over and above that, navigation remedies have a few unique issues that you may want to
contemplate, these kinds of as:

  • How conveniently can you aid navigation wherever the locations may reside in distinct
    modules? Particularly for tasks that go with a “feature module” improvement design,
    it is very likely that you will need a display screen in module A to be equipped to navigate to a display screen in
    module B.

  • Are there apparent patterns for making use of @Preview? In theory, a navigation option
    really should not get in the way of utilizing @Preview for monitor-degree composables, but it would
    be agonizing if it did.

  • Does the resolution function for progress targets past Android? Perhaps you are not
    arranging on Compose for Desktop or Compose for Web or
    Compose for iOS or
    Compose for Consoles. If you are, you
    are heading to want to take into consideration if and how navigation ties into your Kotlin/Multiplatform
    ambitions.


This is not a full list — if there are issues that you consider are relatively common
that I skipped, access out!