JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
16.24k stars 1.18k forks source link

FlowRow NoSuchElementException #4557

Closed dolz-r2 closed 7 months ago

dolz-r2 commented 7 months ago

Describe the bug Exception in thread "AWT-EventQueue-0" java.util.NoSuchElementException at androidx.compose.foundation.layout.FlowLayoutKt.minIntrinsicMainAxisSize(FlowLayout.kt:486) at androidx.compose.foundation.layout.FlowLayoutKt.access$minIntrinsicMainAxisSize(FlowLayout.kt:1) at androidx.compose.foundation.layout.FlowLayoutKt$flowMeasurePolicy$1.minIntrinsicMainAxisSize(FlowLayout.kt:365) at androidx.compose.foundation.layout.FlowLayoutKt$flowMeasurePolicy$1.minIntrinsicWidth(FlowLayout.kt:290) at androidx.compose.ui.node.IntrinsicsPolicy.minIntrinsicWidth(IntrinsicsPolicy.kt:37) at androidx.compose.ui.node.InnerNodeCoordinator.minIntrinsicWidth(InnerNodeCoordinator.kt:133) at androidx.compose.ui.node.NodeMeasuringIntrinsics$DefaultIntrinsicMeasurable.measure-BRTryo0(LayoutModifierNode.kt:257) at androidx.compose.foundation.layout.FillNode.measure-3p2s80s(Size.kt:698) at androidx.compose.ui.node.LayoutModifierNode$minIntrinsicWidth$1.measure-3p2s80s(LayoutModifierNode.kt:77) at androidx.compose.ui.node.NodeMeasuringIntrinsics.minWidth$ui(LayoutModifierNode.kt:181) at androidx.compose.ui.node.LayoutModifierNode.minIntrinsicWidth(LayoutModifierNode.kt:75) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.minIntrinsicWidth(LayoutModifierNodeCoordinator.kt:129) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.minIntrinsicWidth(LayoutNodeLayoutDelegate.kt:711) at androidx.compose.foundation.layout.IntrinsicMeasureBlocks$VerticalMinWidth$1$1.invoke(RowColumnImpl.kt:453) at androidx.compose.foundation.layout.IntrinsicMeasureBlocks$VerticalMinWidth$1$1.invoke(RowColumnImpl.kt:451) at androidx.compose.foundation.layout.RowColumnImplKt.intrinsicCrossAxisSize(RowColumnImpl.kt:599) at androidx.compose.foundation.layout.RowColumnImplKt.intrinsicSize(RowColumnImpl.kt:546) at androidx.compose.foundation.layout.RowColumnImplKt.access$intrinsicSize(RowColumnImpl.kt:1) at androidx.compose.foundation.layout.IntrinsicMeasureBlocks$VerticalMinWidth$1.invoke(RowColumnImpl.kt:451) at androidx.compose.foundation.layout.IntrinsicMeasureBlocks$VerticalMinWidth$1.invoke(RowColumnImpl.kt:450) at androidx.compose.foundation.layout.RowColumnImplKt$rowColumnMeasurePolicy$1.minIntrinsicWidth(RowColumnImpl.kt:98) at androidx.compose.ui.node.IntrinsicsPolicy.minIntrinsicWidth(IntrinsicsPolicy.kt:37) at androidx.compose.ui.node.InnerNodeCoordinator.minIntrinsicWidth(InnerNodeCoordinator.kt:133) at androidx.compose.foundation.layout.MinIntrinsicWidthModifier.calculateContentConstraints-l58MMJ0(Intrinsic.kt:117) at androidx.compose.foundation.layout.IntrinsicSizeModifier.measure-3p2s80s(Intrinsic.kt:252) at androidx.compose.ui.node.BackwardsCompatNode.measure-3p2s80s(BackwardsCompatNode.kt:311) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116) at androidx.compose.foundation.layout.WrapContentNode.measure-3p2s80s(Size.kt:1006) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1499) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2300) at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:471) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:234) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:133) at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:113) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:35) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:560) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:539) at androidx.compose.foundation.layout.RowColumnMeasurementHelper.measureWithoutPlacing-EkL-Y(RowColumnMeasurementHelper.kt:172) at androidx.compose.foundation.layout.RowColumnImplKt$rowColumnMeasurePolicy$1.measure-3p2s80s(RowColumnImpl.kt:72) at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:126) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1499) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2300) at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:471) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:234) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:133) at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:113) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:35) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:560) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:539) at androidx.compose.foundation.layout.RowColumnMeasurementHelper.measureWithoutPlacing-EkL-Y(RowColumnMeasurementHelper.kt:172) at androidx.compose.foundation.layout.RowColumnImplKt$rowColumnMeasurePolicy$1.measure-3p2s80s(RowColumnImpl.kt:72) at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:126) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1499) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2300) at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:471) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:234) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:133) at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:113) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:35) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:560) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:539) at androidx.compose.foundation.layout.BoxKt$boxMeasurePolicy$1.measure-3p2s80s(Box.kt:114) at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:126) at androidx.compose.foundation.layout.PaddingNode.measure-3p2s80s(Padding.kt:397) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116) at androidx.compose.foundation.layout.FillNode.measure-3p2s80s(Size.kt:698) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1499) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2300) at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:471) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:234) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:133) at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:113) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:35) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:560) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:539) at androidx.compose.animation.AnimatedEnterExitMeasurePolicy.measure-3p2s80s(AnimatedVisibility.kt:795) at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:126) at androidx.compose.ui.graphics.BlockGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:578) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116) at androidx.compose.animation.AnimatedContentKt$AnimatedContent$6$1$1.invoke-3p2s80s(AnimatedContent.kt:763) at androidx.compose.animation.AnimatedContentKt$AnimatedContent$6$1$1.invoke(AnimatedContent.kt:762) at androidx.compose.ui.layout.LayoutModifierImpl.measure-3p2s80s(LayoutModifier.kt:291) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1499) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2300) at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:471) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:234) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:133) at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:113) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:35) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:560) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:539) at androidx.compose.animation.AnimatedContentMeasurePolicy.measure-3p2s80s(AnimatedContent.kt:814) at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:126) at androidx.compose.animation.AnimatedContentTransitionScopeImpl$SizeModifier.measure-3p2s80s(AnimatedContent.kt:598) at androidx.compose.ui.node.BackwardsCompatNode.measure-3p2s80s(BackwardsCompatNode.kt:311) 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) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1499) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2300) at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:471) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:234) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:133) at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:113) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1495) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:35) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:560) at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui(LayoutNode.kt:1140) at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui$default(LayoutNode.kt:1131) at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA(MeasureAndLayoutDelegate.kt:323) at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:458) at androidx.compose.ui.node.MeasureAndLayoutDelegate.access$remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:39) at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout(MeasureAndLayoutDelegate.kt:344) at androidx.compose.ui.platform.SkiaBasedOwner.measureAndLayout(SkiaBasedOwner.skiko.kt:246) at androidx.compose.ui.node.Owner.measureAndLayout$default(Owner.kt:223) at androidx.compose.ui.ComposeScene.render(ComposeScene.skiko.kt:546) at androidx.compose.ui.awt.ComposeBridge$skikoView$1$onRender$1.invoke(ComposeBridge.desktop.kt:178) at androidx.compose.ui.awt.ComposeBridge$skikoView$1$onRender$1.invoke(ComposeBridge.desktop.kt:177) at androidx.compose.ui.awt.ComposeBridge.catchExceptions(ComposeBridge.desktop.kt:150) at androidx.compose.ui.awt.ComposeBridge.access$catchExceptions(ComposeBridge.desktop.kt:64) at androidx.compose.ui.awt.ComposeBridge$skikoView$1.onRender(ComposeBridge.desktop.kt:177) at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:548) at org.jetbrains.skiko.redrawer.AWTRedrawer.update(AWTRedrawer.kt:54) at org.jetbrains.skiko.redrawer.Direct3DRedrawer$frameDispatcher$1.invokeSuspend(Direct3DRedrawer.kt:49) at org.jetbrains.skiko.redrawer.Direct3DRedrawer$frameDispatcher$1.invoke(Direct3DRedrawer.kt) at org.jetbrains.skiko.redrawer.Direct3DRedrawer$frameDispatcher$1.invoke(Direct3DRedrawer.kt) at org.jetbrains.skiko.FrameDispatcher$job$1.invokeSuspend(FrameDispatcher.kt:33) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90) Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@7d0b713, SwingDispatcher@12ca039f]

Affected platforms

Versions

To Reproduce Steps and/or the code snippet to reproduce the behavior:

if (state.selected.isNotEmpty()) {
          FlowRow(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
              for (chip in state.selected) {
                   state.options[chip]?.let { name ->
                       InputChip(
                           selected = true,
                           label = { Text(text = name) },
                           onClick = { state.onUnselect(chip) }
                       )
                   }
              }
          }
      }

When user adds a chip to selected in state and leaves the screen and then navigate back to the screen (the selected chip was saved, so now state.selected will have one chip in it. The error occures.

Expected behavior No error

Screenshots N.A.

Additional context N.A.

m-sasha commented 7 months ago

Can you post a complete, compilable, reproducer? The code you posted is missing the "state" declaration.

dolz-r2 commented 7 months ago

@m-sasha my appologies if my example did not give all the information you needed as a lot of code depends on it and I cannot tell where the problem really comes from. Below is the state class. If needed, I can also publish the full function of the code I published before.

data class ChipSelectSearchState(
    val selected: Collection<Long> = listOf(),
    val options: Map<Long, String> = mapOf(),
    val onSelect: (Long) -> Unit,
    val onUnselect: (Long) -> Unit,
)
m-sasha commented 7 months ago

@dolz-r2 We need to reproduce the problem ourselves so we can fix it. To do that we need a code sample that demonstrates the problem.

Unfortunately even with the ChipSelectSearchState, we can't reproduce it. It's not clear what you mean by "When user adds a chip to selected in state and leaves the screen and then navigate back to the screen". How does the user add the chip to selected? What do you mean by "leaves the screen and then navigate back to the screen"? What is a "screen"? How does the user leave it and then navigates back?

dolz-r2 commented 7 months ago

@m-sasha when i was trying to recreate the bug in a sample project, i saw that FlowRow is still experimental. My apologies for disturbing you unnecessarily. I will try to use a different solution, until it is out of experimental. Thank you for your time

m-sasha commented 7 months ago

@dolz-r2 it's experimental, but we still want to fix any bugs in it. If you could make a reproducer, it would help us a lot.

okushnikov commented 4 months ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.