accompanist icon indicating copy to clipboard operation
accompanist copied to clipboard

[Navigation] The target value must have an associated anchor

Open ghost opened this issue 3 years ago • 18 comments

After a re-compose my ModalBottomSheetLayout the sheetContent looses it's associated anchor. My sheetContent is dynamic, and i set it using mutableStates. User can tap different buttons and I set the sheetContent based on that. The scrim covers the view and I can see an Lottie animations run in the background. But as soon as I touch the Scrim it dies with the error

java.lang.IllegalArgumentException: The target value must have an associated anchor.

The example I added below will crash with the same error.

Steps to reproduce

typealias SheetContent = @Composable ColumnScope.() -> Unit

class Fragment: blablabla() {

// fragment stuff 
var sheetContent by remember { mutableStateOf<SheetContent?>(null) }
val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Expanded)
 
 setContent {
      ModalBottomSheetLayout(
             sheetContent = { Column(content = sheetContent ?: { }) },
               sheetState = sheetState
       ) {
             Colum {
                  // Content
             }
       }
 }
}

Expected behavior I should be able to have an empty sheetContent in my ModalBottomSheet. Right now having something without size crash if you expand the sheet.

ghost avatar Dec 07 '21 08:12 ghost

Is this for Accompanist Navigation Material or for Material's ModalBottomSheetLayout? I don't see any use of Accompanist APIs here so I'm suspecting you'll want the Material issue tracker instead: https://issuetracker.google.com/issues?q=componentid:742043

However, this is a known issue that stems from the current API design; afaik it will be revised at some point. In the meantime, this issue isn't really feasible to fix and it could be argued that a sheet without any content is an illegal state in any case.

We work around it in Accompanist ourselves too: https://github.com/google/accompanist/blob/main/navigation-material/src/main/java/com/google/accompanist/navigation/material/SheetContentHost.kt#L165

jossiwolf avatar Dec 08 '21 10:12 jossiwolf

We also see this issue causing crashes for our users in a live app.

However, i think the case that @jossiwolf linked is not entirely same as the original post.

The original error, what we also see in our crash reports:

java.lang.IllegalArgumentException: The target value must have an associated anchor.

The stack trace in the linked Google issue tracker:

java.lang.IllegalArgumentException: The initial value must have an associated anchor.

Note target vs initial.

I believe the issue is coming from ModalBottomSheetState.internalHide(), which calls snapTo(), and that can throw this exception. Maybe we should catch all exceptions there?

WonderCsabo avatar Feb 16 '22 16:02 WonderCsabo

@WonderCsabo Do you have a reproducible sample by chance? I understand it might not be super easy to isolate. The full stacktrace (feel free to redact your package name) would be helpful, too.

The original issue seems to relate to Material's ModalBottomSheetLayout. A modal bottom sheet always has an anchor for the Hidden, except for when it doesn't have any anchors at all (this is the case when the sheet content hasn't been positioned yet). The only way I can see us getting into that state is:

  1. We pop the current sheet destination off the back stack, setting the sheet content to EmptySheet
  2. ModalBottomSheetLayout is recomposed since the sheetContent has been changed
  3. ~ModalBottomSheetLayout's internal sheetHeightState gets reinitialized/set to null~ ?
  4. At the same time, the SheetContentHost's DisposableEffect leaves the composition, we call internalHide()
  5. The state currently doesn't have any anchors, so the target value can't be found

Just thinking out loud here though, any additional info for a repro would be appreciated. It's unlikely for all of these things to happen in the right order and at the same time. Maybe there's another way to get into this state.

jossiwolf avatar Feb 17 '22 13:02 jossiwolf

@jossiwolf here is the full stacktrace:

Fatal Exception: java.lang.IllegalArgumentException: The target value must have an associated anchor.
       at androidx.compose.material.SwipeableState$snapTo$$inlined$collect$1.emit(Collect.kt:136)
       at kotlinx.coroutines.flow.FlowKt__LimitKt.emitAbort$FlowKt__LimitKt(Limit.kt:73)
       at kotlinx.coroutines.flow.FlowKt__LimitKt.access$emitAbort$FlowKt__LimitKt(Limit.kt:1)
       at kotlinx.coroutines.flow.FlowKt__LimitKt$take$lambda-7$$inlined$collect$1.emit(Collect.kt:138)
       at androidx.compose.material.SwipeableState$special$$inlined$filter$1$2.emit(Collect.kt:137)
       at kotlinx.coroutines.flow.internal.SafeCollectorKt$emitFun$1.invoke(SafeCollector.kt:15)
       at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:77)
       at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:59)
       at androidx.compose.runtime.SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1.invokeSuspend(SnapshotFlow.kt:134)
       at androidx.compose.runtime.SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1.invoke(SnapshotFlow.kt:2)
       at kotlinx.coroutines.flow.SafeFlow.collectSafely(SafeFlow.java:61)
       at kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:212)
       at androidx.compose.material.SwipeableState$special$$inlined$filter$1.collect(SafeCollector.common.kt:114)
       at kotlinx.coroutines.flow.FlowKt__LimitKt$take$$inlined$unsafeFlow$1.collect(SafeCollector.common.kt:116)
       at androidx.compose.material.SwipeableState.snapTo(SwipeableState.java:943)
       at com.google.accompanist.navigation.material.SheetContentHostKt.internalHide(SheetContentHostKt.java:188)
       at com.google.accompanist.navigation.material.SheetContentHostKt.access$internalHide(SheetContentHostKt.java:1)
       at com.google.accompanist.navigation.material.SheetContentHostKt$SheetContentHost$2$2$1.invokeSuspend(SheetContentHost.kt:145)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
       at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
       at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
       at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
       at android.os.Handler.handleCallback(Handler.java:888)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at android.os.Looper.loop(Looper.java:213)
       at android.app.ActivityThread.main(ActivityThread.java:8178)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)

Unfortunately i could never reproduce this, but lot of our users can, according to the crash reports.

WonderCsabo avatar Feb 17 '22 13:02 WonderCsabo

I am able to reproduce the java.lang.IllegalArgumentException: The initial value must have an associated anchor. issue in the sample app of my Compose Destinations library. I just need to open the bottom sheet screen, force process death and restart app from recents task.

2022-03-14 23:10:40.385 7991-7991/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.ramcosta.samples.destinationstodosample, PID: 7991
    java.lang.IllegalArgumentException: The initial value must have an associated anchor.
        at androidx.compose.material.SwipeableState.ensureInit$material_release(Swipeable.kt:138)
        at androidx.compose.material.SwipeableKt$swipeable$3.invoke(Swipeable.kt:594)
        at androidx.compose.material.SwipeableKt$swipeable$3.invoke(Swipeable.kt:573)
        at androidx.compose.ui.ComposedModifierKt$materialize$result$1.invoke(ComposedModifier.kt:263)
        at androidx.compose.ui.ComposedModifierKt$materialize$result$1.invoke(ComposedModifier.kt:258)
        at androidx.compose.ui.Modifier$Element$DefaultImpls.foldIn(Modifier.kt:107)
        at androidx.compose.ui.ComposedModifier.foldIn(ComposedModifier.kt:172)
        at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149)
        at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149)
        at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149)
        at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149)
        at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149)
        at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149)
        at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149)
        at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149)
        at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149)
        at androidx.compose.ui.ComposedModifierKt.materialize(ComposedModifier.kt:258)
        at androidx.compose.ui.layout.LayoutKt$materializerOf$1.invoke-Deg8D_g(Layout.kt:221)
        at androidx.compose.ui.layout.LayoutKt$materializerOf$1.invoke(Layout.kt:220)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.material.SurfaceKt$Surface$6.invoke(Surface.kt:302)
        at androidx.compose.material.SurfaceKt$Surface$6.invoke(Surface.kt:255)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
        at androidx.compose.material.SurfaceKt.Surface-F-jzlyU(Surface.kt:252)
        at androidx.compose.material.SurfaceKt.Surface-F-jzlyU(Surface.kt:110)
        at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:262)
        at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:247)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
        at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
        at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
        at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:140)
        at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2158)
        at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2404)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2585)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2571)
        at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:247)
        at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
        at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:2571)
        at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:2547)
        at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:620)
        at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:786)
        at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:105)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:456)

@jossiwolf Is this a known issue? Should I open a new issue since I found reproduction steps?

raamcosta avatar Mar 15 '22 13:03 raamcosta

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

github-actions[bot] avatar Apr 15 '22 03:04 github-actions[bot]

@jossiwolf we still see this issue in our crash reports. Please reopen.

WonderCsabo avatar Apr 20 '22 09:04 WonderCsabo

@WonderCsabo I had same problem, I added 1.dp space fixed problem

sheetContent = {
     Spacer(modifier = Modifier.height(1.dp))
    when(selectedBottomSheet){
    screen1 -> ..
    screen2 -> ..
    else ->{}
}

I hope this will help.

kemalfaust avatar Apr 25 '22 13:04 kemalfaust

adding Spacer(modifier = Modifier.height(1.dp)) to sheet content solved my problem

ModalBottomSheetLayout(
    modifier = Modifier.fillMaxSize(),
    sheetState = modalBottomSheetState,
    sheetContent = {
        Spacer(modifier = Modifier.height(1.dp))

      currentBottomSheet?.let {
          BottomSheetDecider(bottomSheetType = it) {
              closeSheet()
          }
      }
    },
    sheetElevation = 16.dp,
) 

seunAwonugba avatar Jun 22 '22 23:06 seunAwonugba

When I wanted to show the bottom sheet half expanded, Spacer 1.dp height was not enough. I needed more than 200.dp empty Box() there.

Ryszardenko avatar Jul 26 '22 15:07 Ryszardenko

Apologies for the radio silence! This is being tracked and fixed upstream, it will still take a bit, unfortunately. We're closer though :)

jossiwolf avatar Sep 23 '22 16:09 jossiwolf

I found a solution that works with all the screen sizes

In modalBottomSheetLayout you have to put in sheetContent empty Box which is at least 51% screen height.

In my case:

                ModalBottomSheetLayout(
                    sheetContent = {
                        Box {
                            Box(
                                modifier = Modifier.fillMaxSize(0.51f),
                            )

                           // your content here //
                        }
                    },
                    sheetState = rememberModalBottomSheetState(),
                )

Ryszardenko avatar Sep 25 '22 15:09 Ryszardenko

My use case is opening multiple state bottom sheet with dynamic content. I have used the below defined approach.

val scaffoldState = rememberScaffoldState() val bottomState = rememberModalBottomSheetState( ModalBottomSheetValue.Hidden, confirmStateChange = { false }) val (selected, setSelected) = remember(calculation = { mutableStateOf(-1) })

ModalBottomSheetLayout( sheetState = bottomState, ), sheetContent = { Spacer(modifier = Modifier.height(1.dp)) Box(Modifier.defaultMinSize(minHeight = dimensionResource(id = R.dimen.txt_1sdp))) { when (selected) { -1 -> { closeSheet() } 0 -> { }) { // Main View Content here .... }

Fatal Exception: java.lang.IllegalArgumentException: The initial value must have an associated anchor. at androidx.compose.material.SwipeableState.ensureInit$material_release(Swipeable.kt:138) at androidx.compose.material.SwipeableKt$swipeable$3.invoke(Swipeable.kt:594) at androidx.compose.material.SwipeableKt$swipeable$3.invoke(Swipeable.kt:573) at androidx.compose.ui.ComposedModifierKt$materialize$result$1.invoke(ComposedModifier.kt:263) at androidx.compose.ui.ComposedModifierKt$materialize$result$1.invoke(ComposedModifier.kt:258) at androidx.compose.ui.Modifier$Element$DefaultImpls.foldIn(Modifier.kt:107) at androidx.compose.ui.ComposedModifier.foldIn(ComposedModifier.kt:172) at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149) at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149) at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149) at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149) at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149) at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149) at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149) at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149) at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:149) at androidx.compose.ui.ComposedModifierKt.materialize(ComposedModifier.kt:258) at androidx.compose.ui.layout.LayoutKt$materializerOf$1.invoke-Deg8D_g(Layout.kt:221) at androidx.compose.ui.layout.LayoutKt$materializerOf$1.invoke(Layout.kt:220) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.ComposablesKt.ReusableComposeNode(ComposablesKt.java:441) at androidx.compose.material.SurfaceKt$Surface$6.invoke(Surface.kt:302) at androidx.compose.material.SurfaceKt$Surface$6.invoke(Surface.kt:255) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228) at androidx.compose.material.SurfaceKt.Surface-F-jzlyU(Surface.kt:252) at androidx.compose.material.SurfaceKt.Surface-F-jzlyU(Surface.kt:110) at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:262) at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:247) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116) at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127) at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127) at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:140) at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2158) at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2404) at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2585) at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2571) at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:247) at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(SnapshotStateKt.java:1) at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:2571) at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:2547) at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:620) at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:786) at androidx.compose.runtime.Recomposer.access$setCloseCause$p(Recomposer.kt:105) at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:456) at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:425) at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34) at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109) at androidx.compose.ui.platform.AndroidUiDispatcher.access$setScheduledFrameDispatch$p(AndroidUiDispatcher.android.kt:41) at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1230) at android.view.Choreographer.doCallbacks(Choreographer.java:1029) at android.view.Choreographer.doFrame(Choreographer.java:925) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1217) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:233) at android.os.Looper.loop(Looper.java:344) at android.app.ActivityThread.main(ActivityThread.java:8212) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)

Facing this crash which is not reproducable. Please help me to fix this.

Pooja1018 avatar Oct 13 '22 08:10 Pooja1018

I found a solution that works with all the screen sizes

In modalBottomSheetLayout you have to put in sheetContent empty Box which is at least 51% screen height.

In my case:

                ModalBottomSheetLayout(
                    sheetContent = {
                        Box {
                            Box(
                                modifier = Modifier.fillMaxSize(0.51f),
                            )

                           // your content here //
                        }
                    },
                    sheetState = rememberModalBottomSheetState(),
                )

Pooja1018 avatar Oct 13 '22 08:10 Pooja1018

using same issue didn't fixed my problem

Pooja1018 avatar Oct 13 '22 08:10 Pooja1018

@Pooja1018 if you open half expanded bottom sheet, the box height must be at least 0.51 Screen Size. Are you sure your ModalBottomSheetLayout does not have any parent which is not as height as a screen?

Ryszardenko avatar Oct 13 '22 09:10 Ryszardenko

@Pooja1018 if you open half expanded bottom sheet, the box height must be at least 0.51 Screen Size. Are you sure your ModalBottomSheetLayout does not have any parent which is not as height as a screen?

@Ryszardenko the initial state of my bottom sheet remain hidden and its a modalBottomsheet.

val bottomState = rememberModalBottomSheetState( ModalBottomSheetValue.Hidden, confirmStateChange = { false })

ModalBottomSheetLayout( sheetState = bottomState, ), sheetContent = { Spacer(modifier = Modifier.height(1.dp)) Box(Modifier.defaultMinSize(minHeight = dimensionResource(id = R.dimen.txt_1sdp))) { when (selected) { -1 -> { closeSheet() } 0 -> { //screen 1 } }

this is how it goes

Pooja1018 avatar Oct 13 '22 12:10 Pooja1018

Change Box(Modifier.defaultMinSize(minHeight = dimensionResource(id = R.dimen.txt_1sdp)))

to

Box(modifier = Modifier.fillMaxSize(0.51f))

Ryszardenko avatar Oct 14 '22 05:10 Ryszardenko

I found a solution that works with all the screen sizes In modalBottomSheetLayout you have to put in sheetContent empty Box which is at least 51% screen height. In my case:

                ModalBottomSheetLayout(
                    sheetContent = {
                        Box {
                            Box(
                                modifier = Modifier.fillMaxSize(0.51f),
                            )

                           // your content here //
                        }
                    },
                    sheetState = rememberModalBottomSheetState(),
                )

Why then not do this:

ModalBottomSheetLayout(
                    sheetContent = {
                        Box {
                            Box(
                                modifier = Modifier.fillMaxSize(), <--- full screen
                            )

                           // your content here //
                        }
                    },
                    sheetState = rememberModalBottomSheetState(),
                )

Monabr avatar Dec 27 '22 01:12 Monabr

Why every do this if in code we already have this?

image

Monabr avatar Dec 27 '22 01:12 Monabr

Why every do this if in code we already have this?

image

Because this way you will always have full screen bottom sheet

Ryszardenko avatar Dec 29 '22 08:12 Ryszardenko

For me this

adding Spacer(modifier = Modifier.height(1.dp)) to sheet content solved my problem

ModalBottomSheetLayout(
    modifier = Modifier.fillMaxSize(),
    sheetState = modalBottomSheetState,
    sheetContent = {
        Spacer(modifier = Modifier.height(1.dp))

      currentBottomSheet?.let {
          BottomSheetDecider(bottomSheetType = it) {
              closeSheet()
          }
      }
    },
    sheetElevation = 16.dp,
) 

and this

I found a solution that works with all the screen sizes

In modalBottomSheetLayout you have to put in sheetContent empty Box which is at least 51% screen height.

In my case:

                ModalBottomSheetLayout(
                    sheetContent = {
                        Box {
                            Box(
                                modifier = Modifier.fillMaxSize(0.51f),
                            )

                           // your content here //
                        }
                    },
                    sheetState = rememberModalBottomSheetState(),
                )

Does not help unfortunately.

Monabr avatar Dec 30 '22 13:12 Monabr

v0.28.1 addresses this issue. Please let us know if you can still reproduce it with this version.

jossiwolf avatar Jan 12 '23 07:01 jossiwolf

For anyone interested - this has been fixed in 0.29.0-alpha instead of 0.28.1.

scana avatar Jan 23 '23 13:01 scana

Hi @jossiwolf we still see the same crash with 0.30.0:

Fatal Exception: java.lang.IllegalArgumentException: The initial value must have an associated anchor.
       at androidx.compose.material.SwipeableState.ensureInit$material_release(SwipeableState.java:138)
       at androidx.compose.material.SwipeableKt$swipeable$3.invoke(Swipeable.kt:594)
       at androidx.compose.material.SwipeableKt$swipeable$3.invoke(Swipeable.kt:573)
       at androidx.compose.ui.ComposedModifierKt$materialize$result$1.invoke(ComposedModifier.kt:278)
       at androidx.compose.ui.ComposedModifierKt$materialize$result$1.invoke(ComposedModifier.kt:273)
       at androidx.compose.ui.Modifier$Element.foldIn(Modifier.kt:114)
       at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:272)
       at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:272)
       at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:272)
       at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:272)
       at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:272)
       at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:272)
       at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:272)
       at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:272)
       at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:272)
       at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:272)
       at androidx.compose.ui.ComposedModifierKt.materialize(ComposedModifier.kt:273)
       at androidx.compose.ui.layout.LayoutKt$materializerOf$1.invoke-Deg8D_g(Layout.kt:193)
       at androidx.compose.ui.layout.LayoutKt$materializerOf$1.invoke(Layout.kt:192)
       at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
       at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
       at androidx.compose.material.SurfaceKt$Surface$1.invoke(Surface.kt:195)
       at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
       at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
       at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
       at androidx.compose.material.SurfaceKt.Surface-F-jzlyU(Surface.kt:114)
       at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:341)
       at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:326)
       at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
       at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
       at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
       at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.java:145)
       at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2375)
       at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(ComposerImpl.java:2643)
       at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3260)
       at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3238)
       at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(SnapshotStateKt__DerivedState.kt:341)
       at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(SnapshotState.kt:1)
       at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3238)
       at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3203)
       at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:771)
       at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:1031)
       at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:125)
       at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:534)
       at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:503)
       at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
       at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.java:109)
       at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.java:41)
       at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1229)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
       at android.view.Choreographer.doCallbacks(Choreographer.java:899)
       at android.view.Choreographer.doFrame(Choreographer.java:827)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
       at android.os.Handler.handleCallback(Handler.java:942)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loopOnce(Looper.java:201)
       at android.os.Looper.loop(Looper.java:288)
       at android.app.ActivityThread.main(ActivityThread.java:7884)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

I am unable to reproduce it locally though (for now).

scana avatar Apr 17 '23 13:04 scana