Невозможно представить размер 214748364 в ограничениях

Я только что создал простой Composable и хотел отобразить его с помощью , но при реализации решения я наткнулся на эту ошибку на этапе измерения.

      java.lang.IllegalArgumentException: Can't represent a size of 214748364 in Constraints
        at androidx.compose.ui.unit.Constraints$Companion.bitsNeedForSize(Constraints.kt:408)
        at androidx.compose.ui.unit.Constraints$Companion.createConstraints-Zbe2FdA$ui_unit_release(Constraints.kt:368)
        at androidx.compose.ui.unit.ConstraintsKt.Constraints(Constraints.kt:438)
        at androidx.compose.ui.unit.ConstraintsKt.Constraints$default(Constraints.kt:423)
        at com.gmarsk.aiare.MainActivity$InstructionsScreen$DisplayCard$1.measure-3p2s80s(MainActivity.kt:514)
        at androidx.compose.ui.node.InnerPlaceable.measure-BRTryo0(InnerPlaceable.kt:54)

Это было, когда я пробовал это

      val sampleComposable = measurables[1].measure(
                Constraints(
                    minHeight = constraints.maxHeight * 7 / 10,
                )
            )

Кто-нибудь натыкался на это раньше? Каково решение, если это не ошибка, и в этом случае, пожалуйста, дайте мне знать.

Теперь проблема здесь, я думаю, заключается в том, что я вложил два Composables,

      Layout(
content = {
 Dummy1()
 Dummy2()
 NestedLayoutComposable() // It contains a Layout Composable itself
}{ measurables, constraints ->
 val nlc = measurables[2].measure(
  Constraints(
   minHeight = constraints.maxHeight * 7/10
  )
 )
 layout(constraints.maxWidth, constraints.maxHeight){
  nls.place(0, 0)
 }
}
)

Где у nestedLayoutComposable снова есть макет, и именно здесь происходит сбой, именно в этой строке

                  Layout(
                content = {
                    Text(text = "Random")
                    Box {
                        Image(painter = AppUtils.getRandomImagePainter(), contentDescription = "")
                    }
                }
            ) { measurables, constraints ->
                val text = measurables[0].measure(constraints)
/*This line -->*/   val image = measurables[1].measure(
                    Constraints(
                        maxWidth = constraints.maxWidth * 90 / 100,
                        minHeight = constraints.maxHeight * 7 / 10
                    )
                )

                layout(constraints.maxWidth, constraints.maxHeight) {
                    instruction.place(
                        (constraints.maxWidth - instruction.width) / 2,
                        0
                    )
                    illustration.place(
                        (constraints.maxWidth - illustration.width) / 2,
                        illustration.height / 2
                    )
                }
            }

Так что я знаю, что проблема с LayoutКомпонуемые вложены друг в друга, но это все еще не объясняет, ПОЧЕМУ возникает ошибка и КАК ее решить, и поэтому это основные вопросы этого поста, и это то, что я ожидаю от ответов, спасибо.

5 ответов

В моем случае аналогичный сбой был вызван прокручиваемым столбцом внутри другого прокручиваемого столбца. Проверьте, нет ли у вас такого случая в вашей иерархии компоновки.

В вашем случае это потому, что вы ничего не можете измерить с помощью множителейConstraints.Infinity. Потому что в исходном коде функции createConstraints

       internal fun createConstraints(
        minWidth: Int,
        maxWidth: Int,
        minHeight: Int,
        maxHeight: Int
    ): Constraints {

        //  Because of this check and bitsNeedForSize
      
        val heightVal = if (maxHeight == Infinity) minHeight else maxHeight
        val heightBits = bitsNeedForSize(heightVal)

        val widthVal = if (maxWidth == Infinity) minWidth else maxWidth
        val widthBits = bitsNeedForSize(widthVal)
}

преобразуетheightValдо 0, когда переданная высота равна Constraints.Infinity. При ее изменении вы отправляете значение вbitsNeedForSizeэто переполняет максимальный диапазон и вылетает с

          private fun bitsNeedForSize(size: Int): Int {
        return when {
            size < MaxNonFocusMask -> MaxNonFocusBits
            size < MinNonFocusMask -> MinNonFocusBits
            size < MinFocusMask -> MinFocusBits
            size < MaxFocusMask -> MaxFocusBits
            else -> throw IllegalArgumentException(
                "Can't represent a size of $size in " +
                    "Constraints"
            )
        }
    }

Простая проверка должна заключаться в том, является ли используемое вами измерение Constraints.Infinity с использованием hasBoundedHeight или ограничения.min/maxHieght == Constraints.Infinity.

Также следует проверить, чтобы минимальные ограничения не превышали maxConstraints, поэтому

      val wrappedConstraints = constraints.copy(
    minHeight = if (constraints.hasBoundedHeight)
        (constraints.maxHeight * 7 / 10).coerceAtMost(constraints.maxHeight)
    else 0,

)

использование таких ограничений для измерения вашего контента Composables не приведет к сбою.

Также, чтобы установить собственную высоту макета, если он имеет Modifier.fillMaxHeight() или Modifier.height(100), проверив hasFixedHeight, а не бесконечность с помощью hasBoundedHeight.

        val contentHeight = // This some height you get with max, sum or your logic

  val totalHeight = if(hasBoundedHeight && hasFixedHeight){
        constraints.maxHeight
    }else {
        contentHeight.coerceIn(constraints.minHeight.toFloat(), constraints.maxHeight.toFloat())
    }

Если у него нет модификатора размера или модификатора сModifier.height(min=0.dp, max=500.dp)

вы говорите, пусть этот Composable будет таким же большим, как контент, но в пределах диапазона ограничений от модификатора размера.

Эта проверка также гарантирует, что ваш Composable не выйдет из строя при назначении внутреннего модификатора высоты.

       java.lang.IllegalArgumentException: Can't represent a size of 2147483647 in Constraints

Для всех, кто сталкивается с этим, проблема в том, что прокручиваемые представления устанавливают для maxHeight значениеConstraints.Infinity, который представлен какInt.MAX_VALUE. Поэтому, если ваш макет предполагает ограниченную высоту, он переполнит значение int.

Это случилось со мной, когда я попытался использоватьSliderвнутриColumnэто имелоModifier.width(IntrinsicSize.Min)независимо от того, является ли столбец его прямым родителем или нет. Хотя исключение исчезает, когда я использую другую перегрузку ползунка, где вы предоставляете лямбда-выражение дляthumbпараметр, но на этот раз у ползунка нет ползунка. Исключение также исчезает, когда я указываю фиксированную ширину ползунка.

Это ошибка.

Изменить: исправлено, просто необходимо обновить библиотеки.

Редактировать 2: библиотеки были:

  • org.jetbrains.kotlin:kotlin-bom, обновлено с 1.8.0 до 1.9.0
  • androidx.compose:compose-bom, обновлено с 2022.10.00 по 2023.06.01 и соответствующиеandroidTestImplementationхотя я не думаю, что последнее было необходимо, поскольку я не писал тесты

Минимальная версия SDK — 31.

В основном это происходит, когда вы джемуете гораздо больше, чем может отобразить компонуемый объект.

Я воспроизвел его, используя очень длинную строку для элемента списка.

Другие вопросы по тегам