Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Crash on ReadMoreText with IntrinsicSize

Aperta
#126 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

@fornewid ci sta già lavorando.

Dal 8/10/2026.

  • #127 di @fornewid — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
54/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
android, kotlin
Ambito
frontend, mobile

Direzione di ricerca

Start in the CoreReadMoreText implementation and trace how BoxWithConstraints supplies the width used to calculate collapsed text. The proposal identifies replacing it with Box, recording width from BasicText's onTextLayout, and recalculating collapsed text; check the foundation, material, and material3 tests, including intrinsic-height measurement and width changes. Done means intrinsic measurement no longer crashes and the collapsed text updates correctly without public API changes.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug

Problem

ReadMoreText crashes when its parent asks for intrinsic measurements, for example Row(Modifier.height(IntrinsicSize.Max)). This applies to BasicReadMoreText and to the material and material3 wrappers.

java.lang.IllegalStateException: Asking for intrinsic measurements of SubcomposeLayout layouts is not supported. This includes components that are built on top of SubcomposeLayout, such as lazy lists, BoxWithConstraints, TabRow, etc. To mitigate this:

Since 1.7.0 (#93), CoreReadMoreText wraps BasicText in BoxWithConstraints to read constraints.maxWidth for TextMeasurer. BoxWithConstraints is built on SubcomposeLayout, which does not support intrinsic measurements.

A common case is a horizontal carousel whose cards all match the tallest one:

Row(
    modifier = Modifier
        .horizontalScroll(rememberScrollState())
        .height(IntrinsicSize.Max),
) {
    posts.forEach { post ->
        Column(Modifier.width(292.dp).fillMaxHeight()) {
            ReadMoreText(
                text = post.body,
                expanded = false,
                readMoreText = "more",
                readMoreMaxLines = 3,
            )
        }
    }
}

Proposal

BoxWithConstraints is only used for constraints.maxWidth. BasicText already reports the same value through onTextLayout (TextLayoutResult.layoutInput.constraints), and onTextLayout is called only for the real layout, not for intrinsic measurements.

  1. Replace BoxWithConstraints with Box.
  2. Keep maxWidth in a state and update it from onTextLayout.
  3. Compute the collapsed text with remember(maxWidth, ...) instead of LaunchedEffect. ReadMoreState.applyCollapsedText() becomes calculateCollapsedText(), which returns the collapsed text. Its body stays the same.

The collapsed text is still measured from the original text with TextMeasurer. Only the width source changes. No public API changes.

     val textMeasurer = rememberTextMeasurer()
-    val state = remember { ReadMoreState() }
+    var maxWidth by remember { mutableIntStateOf(UnknownWidth) }
+    val collapsedText = remember(
+        textMeasurer,
+        maxWidth,
+        overflowText,
+        readMoreTextWithStyle,
+        style,
+        readMoreStyle,
+        text,
+        readMoreMaxLines,
+        softWrap,
+        inlineContent,
+    ) {
+        if (maxWidth == UnknownWidth) {
+            AnnotatedString("")
+        } else {
+            calculateCollapsedText(
+                textMeasurer = textMeasurer,
+                constraints = Constraints(maxWidth = maxWidth),
+                overflowText = overflowText,
+                readMoreTextWithStyle = readMoreTextWithStyle,
+                style = style,
+                readMoreStyle = readMoreStyle,
+                text = text,
+                readMoreMaxLines = readMoreMaxLines,
+                softWrap = softWrap,
+                inlineContent = inlineContent,
+            )
+        }
+    }
+    val isCollapsible = collapsedText.isNotEmpty()
 ...
-    BoxWithConstraints(
+    Box(
         modifier = modifier
             .then(toggleableModifier)
             .padding(contentPadding),
     ) {
         BasicText(
             text = currentText,
             modifier = Modifier,
             style = style,
-            onTextLayout = onTextLayout,
+            onTextLayout = { result ->
+                maxWidth = result.layoutInput.constraints.maxWidth
+                onTextLayout(result)
+            },
             overflow = TextOverflow.Ellipsis,
             softWrap = softWrap,
             maxLines = if (expanded) Int.MAX_VALUE else readMoreMaxLines,
             inlineContent = inlineContent,
         )
-
-        val constraints = Constraints(maxWidth = constraints.maxWidth)
-        LaunchedEffect(
-            ...
-        ) {
-            state.applyCollapsedText(...)
-        }
     }

Checked with a local prototype

  • verifyRoborazziDebug passes for readmore-foundation, readmore-material and readmore-material3 (168 cases) with no image changes.
  • In Row(Modifier.height(IntrinsicSize.Max)) it no longer crashes, and the last line ends with … more.
  • When the width changes from 300dp to 200dp and then to 320dp, the collapsed text is recalculated each time.
  • Frame timing is the same as now. The first frame shows the original text with an ellipsis, and the next frame shows the collapsed text with "more".

Alternatives considered

  • Capturing the constraints in Modifier.layout {}: its measure block also runs for intrinsic queries, so the state would be written during intrinsic passes. onTextLayout runs only for the real layout.
  • A custom Layout that measures with TextMeasurer and draws with drawText(): the collapsed text would be ready in the first frame, but it would lose what BasicText provides, such as LinkAnnotation for ToggleArea.More, semantics and inlineContent.
Lingua principale
Kotlin
Stelle
209
Fork
14
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di webtoon/ReadMoreTextView

Tutte le issue di webtoon/ReadMoreTextView

Issue simili

Altre issue su Kotlin

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.