Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Compose TabRow Crash Error : maxHeight(129) must be >= minHeight(130)

We are using the tabRow item in the material3 library in Jetpack Compose

The material3 1.0.1 stable version is being used
( androidx.compose.material3:material3:1.0.1 )

The Galaxy S10 is being used as a development test device, and when the minimum width was changed to 400 through the developer mode, a crash occurred with the error log as shown below

Crash did not occur when the minimum width was not changed to developer mode, which was also checked on other devices and emulators. (Galaxy Z Fold2 5G / Galaxy Z Flip 5G / Galaxy Z Fold25G / Galaxy Note10 5G)

What is the cause of the above bug and what are the solutions?

    java.lang.IllegalArgumentException: maxHeight(129) must be >= minHeight(130)
        at androidx.compose.ui.unit.Constraints.copy-Zbe2FdA(Constraints.kt:170)
        at androidx.compose.ui.unit.Constraints.copy-Zbe2FdA$default(Constraints.kt:158)
        at androidx.compose.material3.TabRowKt$TabRow$2$1$1.invoke-0kLqBqw(TabRow.kt:157)
        at androidx.compose.material3.TabRowKt$TabRow$2$1$1.invoke(TabRow.kt:146)
        at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1.measure-3p2s80s(SubcomposeLayout.kt:591)
        at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:103)
        at androidx.compose.foundation.layout.FillModifier.measure-3p2s80s(Size.kt:658)
        at androidx.compose.ui.node.BackwardsCompatNode.measure-3p2s80s(BackwardsCompatNode.kt:343)
        at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:155)
        at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1077)
        at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1073)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2139)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:130)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:126)
        at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
        at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:126)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:107)
        at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1073)
        at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:36)
        at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:341)
        at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:320)
        at androidx.compose.foundation.layout.BoxKt$boxMeasurePolicy$1.measure-3p2s80s(Box.kt:115)
        at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:103)
        at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:405)
        at androidx.compose.ui.node.BackwardsCompatNode.measure-3p2s80s(BackwardsCompatNode.kt:343)
        at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:155)
        at androidx.compose.foundation.layout.WrapContentModifier.measure-3p2s80s(Size.kt:878)
        at androidx.compose.ui.node.BackwardsCompatNode.measure-3p2s80s(BackwardsCompatNode.kt:343)
        at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:155)
        at androidx.compose.foundation.layout.FillModifier.measure-3p2s80s(Size.kt:658)
        at androidx.compose.ui.node.BackwardsCompatNode.measure-3p2s80s(BackwardsCompatNode.kt:343)
        at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:155)
        at androidx.compose.foundation.layout.PaddingModifier.measure-3p2s80s(Padding.kt:364)
        at androidx.compose.ui.node.BackwardsCompatNode.measure-3p2s80s(BackwardsCompatNode.kt:343)
        at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:155)
        at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1077)                                                                                                                 

It was confirmed that the use of the material library, not the material 3 library, did not cause a crash, and that this was because the functions within the TabRow implementation were implemented differently

// material3

val tabRowHeight = tabMeasurables.fold(initial = 0) { max, curr ->
    maxOf(curr.maxIntrinsicHeight(tabWidth), max)
}

val tabPlaceables = tabMeasurables.map {
    it.measure(
        constraints.copy(
            minWidth = tabWidth,
            maxWidth = tabWidth,
            minHeight = tabRowHeight
        )
    )
}

// material:1.3.1

val tabPlaceables = tabMeasurables.map {
    it.measure(constraints.copy(minWidth = tabWidth, maxWidth = tabWidth))
}
val tabRowHeight = tabPlaceables.maxByOrNull { it.height }?.height ?: 0

val placeable = it.measure(constraints.copy(minHeight = 0))
like image 964
ram Avatar asked Dec 10 '25 08:12

ram


1 Answers

The issue is likely due to how Constraints works.

Original constraints you get has smaller maxHeight than tabRowHeight. When you use Constraints make sure that minWidth/Height is not bigger to max counterpart.

 constraints.copy(
            minWidth = tabWidth,
            maxWidth = tabWidth,
            minHeight = tabRowHeight
            maxHeight = constraints.maxHeight.coerceAtLeast(tabRowHeight)
        )

should solve the issue since we set minimum value of maxHeight to tabRowHeight.

or you can limit minimumHeight's upper bound to maxHeight

constraints.copy(
                minWidth = tabWidth,
                maxWidth = tabWidth,
                minHeight = tabRowHeight.coerceAtMost(constraints.maxHeight)
            )
like image 168
Thracian Avatar answered Dec 11 '25 22:12

Thracian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!