Skip to content
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

[Jetsnack/Owl] Simultaneous taps navigate multiple times #456

Closed
alexvanyo opened this issue Mar 31, 2021 · 3 comments
Closed

[Jetsnack/Owl] Simultaneous taps navigate multiple times #456

alexvanyo opened this issue Mar 31, 2021 · 3 comments

Comments

@alexvanyo
Copy link
Contributor

This affects both Jetsnack (not using androidx.navigation) and Owl (is using androidx.navigation).

If multiple items are tapped at the same time, 2 or more detail screens can be launched. This isn't necessarily a uniquely Jetpack Compose issue, as this plagues a lot of non-Jetpack Compose apps, but I'd be very interesting to see what the "correct" way to handle it is in the Compose world.

Jetsnack:

device-2021-03-31-093840.mp4

Owl:

device-2021-03-31-094457.mp4
@JoseAlcerreca
Copy link
Contributor

Great catch. I uploaded a solution to

https://github.com/JoseAlcerreca/compose-samples/pull/new/owl_multiple_nav_fix

You could also check LocalLifecycleOwner.current.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED) inside the composable destination before using the callback.

@alexvanyo
Copy link
Contributor Author

Thanks for the response! I was exploring potential solutions a bit myself, and for comparison I wanted to share an idea I came up with:

main...alexvanyo:av/token-based-navigation

The rough idea I had was to associate a navigation "action" (a lambda that will ultimately perform .navigate() when invoked) with a token that marks where/when the "action" was composed. Then the deduplication logic for an action could just be a check on whether the current, up-to-date token matches the token that is tagged with the action. In this case, I made the token be a UUID that is updated anytime the backstack changes.

I also took a stab at making that a bit more general here:

main...alexvanyo:av/tokenized-nav-controller

In theory that "token" could be anything: a UUID, the current route, an appropriate sealed class, or some alternate representation of the full backstack. With a TokenPolicy, actions can specify when they should run (based on the current token), and then update the token if they do.

@alexvanyo
Copy link
Contributor Author

Closing this issue, checking the lifecycle of the NavBackStackEntry nicely allows removing simulatenous taps:

/**
 * If the lifecycle is not resumed it means this NavBackStackEntry already processed a nav event.
 *
 * This is used to de-duplicate navigation events.
 */
private fun NavBackStackEntry.lifecycleIsResumed() =
    this.lifecycle.currentState == Lifecycle.State.RESUMED

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants