adrielcafe / voyager

🛸 A pragmatic navigation library for Jetpack Compose
https://voyager.adriel.cafe
MIT License
2.27k stars 109 forks source link

push Screen Crash with Double BottomSheetNavigator and Transition #403

Open RavenLiao opened 2 weeks ago

RavenLiao commented 2 weeks ago

version

v1.0.0

example code

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Navigator(StartScreen) { navigator ->
                GlobalNavigatorWrapper(navigator) {
                    SlideTransition(navigator) {
                        it.Content()
                    }
                }
            }
        }
    }
}

val LocalGlobalNavigator: ProvidableCompositionLocal<Navigator> =
    staticCompositionLocalOf { error("LocalGlobalNavigator not initialized") }

@Composable
fun GlobalNavigatorWrapper(navigator: Navigator, content: @Composable () -> Unit) {
    CompositionLocalProvider(LocalGlobalNavigator provides navigator, content)
}

object StartScreen : Screen {
    private fun readResolve(): Any = StartScreen

    @Composable
    override fun Content() {
        BottomSheetNavigator {
            TabNavigator(TestTab) {
                CurrentScreen()
            }
        }
    }
}

object TestTab : Tab {
    private fun readResolve(): Any = TestTab
    override val options: TabOptions
        @Composable get() = TabOptions(0U, "test")

    @Composable
    override fun Content() {
        val navigator = LocalGlobalNavigator.current

        Column {
            Button(onClick = {
                navigator.push(JumpScreen)
            }) {
                Text(text = "jump with BottomSheetNavigator")
            }
            Button(onClick = {
                navigator.push(Jump2Screen)
            }) {
                Text(text = "jump no BottomSheetNavigator")
            }
        }
    }

}

object JumpScreen : Screen {
    private fun readResolve(): Any = JumpScreen

    @Composable
    override fun Content() {
        BottomSheetNavigator {
            Text(text = "with BottomSheetNavigator")
        }
    }
}

object Jump2Screen : Screen {
    private fun readResolve(): Any = Jump2Screen

    @Composable
    override fun Content() {
        Text(text = "no BottomSheetNavigator")
    }
}

crash log

after clik "jump with BottomSheetNavigator" button will crash:

 java.lang.IllegalArgumentException: Key cafe.adriel.voyager.navigator.bottomSheet.HiddenBottomSheetScreen:currentScreen was used multiple times 
                                                        at androidx.compose.runtime.saveable.SaveableStateHolderImpl$SaveableStateProvider$1$1.invoke(SaveableStateHolder.kt:89)
                                                        at androidx.compose.runtime.saveable.SaveableStateHolderImpl$SaveableStateProvider$1$1.invoke(SaveableStateHolder.kt:88)
                                                        at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:83)
                                                        at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1295)
                                                        at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:984)
                                                        at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:1005)
                                                        at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:1099)
                                                        at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:3599)
                                                        at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:633)
                                                        at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:619)
                                                        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcomposeInto(SubcomposeLayout.kt:500)
                                                        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:472)
                                                        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:463)
                                                        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:447)
                                                        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$Scope.subcompose(SubcomposeLayout.kt:872)
                                                        at androidx.compose.foundation.layout.BoxWithConstraintsKt$BoxWithConstraints$1$1.invoke-0kLqBqw(BoxWithConstraints.kt:69)
                                                        at androidx.compose.foundation.layout.BoxWithConstraintsKt$BoxWithConstraints$1$1.invoke(BoxWithConstraints.kt:67)
                                                        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1.measure-3p2s80s(SubcomposeLayout.kt:709)
                                                        at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:126)
                                                        at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:252)
                                                        at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:251)
                                                        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2303)
                                                        at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:500)
                                                        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:256)
                                                        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
                                                        at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:113)
                                                        at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1617)
                                                        at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:36)
                                                        at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:620)
                                                        at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:596)
                                                        at androidx.compose.animation.AnimatedEnterExitMeasurePolicy.measure-3p2s80s(AnimatedVisibility.kt:851)
                                                        at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:126)
                                                        at androidx.compose.animation.EnterExitTransitionModifierNode.measure-3p2s80s(EnterExitTransition.kt:1156)
                                                        at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116)
                                                        at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:646)
                                                        at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116)

avoid crash

  1. remove BottomSheetNavigator in StartScreen or JumpScreen
  2. remove Transition