TextMeasurer: wat is het en hoe werkt tekstmeting in Compose

Auteur: IT Sectr Gepubliceerd: 2026-07-25 Leestijd: 8 min

TextMeasurer — is een API uit Jetpack Compose die bedoeld is voor het meten van tekstafmetingen voordat deze daadwerkelijk op het scherm wordt weergegeven. In tegenstelling tot de klassieke benadering via Paint.measureText in Android View, biedt TextMeasurer een Compose-native manier om de breedte, hoogte en regelmetriek te verkrijgen, rekening houdend met stijl en beperkingen. Volgens Android Developers Documentation (2025) wordt TextMeasurer actief gebruikt in aangepaste Layout-componenten, geanimeerde bijschriften en adaptieve UI-elementen, waar de tekstgrootte de positionering van andere elementen beïnvloedt.

Belangrijkste punten

  • TextMeasurer — Compose-API voor het meten van tekst vóór het renderen.
  • De methode measure() retourneert TextLayoutResult met metriek van regels en tekens.
  • De API houdt rekening met stijl, lettertype, grootte en containerbeperkingen in pixels.
  • TextMeasurer ondersteunt het meten van één regel en meerregelige tekst.
  • Het meetresultaat wordt gebruikt voor aangepaste lay-out en tekstanimatie.

Wat is TextMeasurer in Jetpack Compose?

TextMeasurer — is een functionele interface uit het pakket androidx.compose.ui.text waarmee tekst in Compose kan worden gemeten zonder directe weergave op het scherm. Het maakt deel uit van de tekst-engine van Compose en werkt op het niveau van de Paragraph API die Skia gebruikt voor rendering.

Het hoofddoel van TextMeasurer is vooraf meten. In Compose wordt de tekstgrootte meestal bepaald nadat Composable al in de Layout is geplaatst. Maar er zijn scenario's waarin u de tekstbreedte vóór compositie moet weten: bijvoorbeeld om te beslissen of een regel in de container past, of om de knopgrootte te berekenen op basis van de tekstlengte.

TextMeasurer lost dit probleem op door de methode measure() te bieden, die TextMeasureRequest (tekst, stijl, beperkingen) ontvangt en TextLayoutResult (metriek, regels, tekens) retourneert. Hiermee kan de ontwikkelaar alle gegevens over de tekst synchroon verkrijgen, zonder een frame vertraging.

Gebruik TextMeasurer wanneer de tekstgrootte de grootte van de bovenliggende component beïnvloedt, bij het maken van geanimeerde tekstovergangen of bij het implementeren van aangepaste Layouts waar tekst naast andere elementen staat.

Hoe werkt TextMeasurer

De TextMeasurer API bestaat uit twee belangrijke entiteiten: rememberTextMeasurer() (instantiecreatie) en measure() (starten van meting). De instantie wordt eenmalig gemaakt voor de hele levenscyclus van de component en wordt hergebruikt voor alle metingen.

kotlin
val textMeasurer = rememberTextMeasurer()

val result = textMeasurer.measure(
    text = "Hello, Compose!",
    style = MaterialTheme.typography.bodyLarge,
    constraints = Constraints(maxWidth = 200, maxHeight = 50)
)

// resultaatbreedte, resultaathoogte, aantal regels

De parameter constraints bepaalt de maximale breedte en hoogte waarbinnen de tekst moet passen. Als de tekst niet binnen de breedte past, wordt deze naar de volgende regel verplaatst. Het meetresultaat bevat TextLayoutResult, waarin u het aantal regels, de positie van elk teken, de breedte van elke regel en de totale tekstgrootte kunt verkrijgen.

TextMeasurer werkt synchroon in de UI-thread en veroorzaakt geen recompositie. Echter, het frequent meten van tekst met verschillende stijlen kan belasting veroorzaken — daarom wordt de instantie via remember gemaakt en hergebruikt.

Eénregelige tekst meten

Het eenvoudigste scenario — meet de breedte van éénregelige tekst om de grootte van de bovenliggende container te bepalen. Bijvoorbeeld voor een knop waarvan de breedte afhangt van de lengte van het label.

kotlin
val textMeasurer = rememberTextMeasurer()
var label by remember { mutableStateOf("Submit") }

val textResult = remember(label) {
    textMeasurer.measure(
        text = label,
        style = MaterialTheme.typography.labelLarge,
        constraints = Constraints(maxWidth = 1000, maxHeight = 100)
    )
}

Box(
    modifier = Modifier
        .width(textResult.size.width.dp)
        .height(40.dp)
        .background(Color.Blue)
        .clickable { onClick() }
) {
    Text(text = label, style = MaterialTheme.typography.labelLarge)
}

In dit voorbeeld garandeert remember(label) dat de meting alleen opnieuw wordt gestart bij wijziging van de tekst. Constraints zijn ingesteld met een grote maxWidth (1000) om regelterugloop te voorkomen — de werkelijke beperking is gelijk aan de tekstbreedte. De breedte van Box wordt ingesteld op de gemeten tekstbreedte, wat het effect van „knop op tekstgrootte" geeft.

Let op: de breedte uit het resultaat moet worden omgezet naar dp via .dp, omdat TextMeasurer afmetingen in pixels retourneert, terwijl Modifier.width Dp verwacht. Gebruik voor nauwkeurigheid density en LocalDensity.current.

Meerregelige tekst meten

Voor meerregelige tekst stelt TextMeasurer u in staat om niet alleen de totale hoogte, maar ook het aantal regels en de positie van elk teken binnen de alinea te bepalen. Dit is nodig bij het maken van aangepaste tekstvelden, chats of editors.

De belangrijkste eigenschappen van TextLayoutResult voor meerregelige tekst: lineCount (aantal regels), getLineTop(index) (Y-coördinaat van het begin van de regel), getLineBottom(index) (Y-coördinaat van het einde), getLineWidth(index) (regelbreedte). Door ze te combineren kunt u interface-elementen precies positioneren ten opzichte van tekstregels.

kotlin
val textMeasurer = rememberTextMeasurer()
val result = textMeasurer.measure(
    text = "Long multiline text that needs to be measured before layout",
    style = MaterialTheme.typography.bodyMedium,
    constraints = Constraints(maxWidth = 150, maxHeight = 300)
)

val linesCount = result.lineCount
val firstLineWidth = result.getLineWidth(0)
val totalHeight = result.size.height

De methode getLineWidth(lineIndex) retourneert de breedte van de opgegeven regel in pixels. Dit kan kleiner zijn dan maxWidth als de regel de containergrens niet bereikt. Door de breedte van elke regel te kennen, kunt u handmatig een uitvul-effect implementeren of inline-elementen naast korte regels plaatsen.

Gebruik getBoundingBox(offset) om de positie van een specifiek teken te verkrijgen, die een Rect retourneert met coördinaten left, top, right, bottom. Dit is handig voor het positioneren van de cursor in aangepaste tekstvelden of voor het markeren van een tekstbereik met animatie.

TextMeasurer in aangepaste componenten

Het krachtigste gebruiksscenario van TextMeasurer — aangepaste Layout-componenten, waar tekst naast andere elementen staat en hun afmetingen onderling afhankelijk zijn. Bijvoorbeeld de widget „Pictogram + tekst", waarbij het pictogram gecentreerd moet worden ten opzichte van de eerste regel tekst, niet het hele blok.

In een standaard Row wordt het pictogram gecentreerd op de hoogte van de hele Row, wat er onnatuurlijk uitziet wanneer tekst 3 regels beslaat en het pictogram één. Met TextMeasurer kunt u de eerste regel meten en het pictogram precies daarop uitlijnen.

kotlin
val textMeasurer = rememberTextMeasurer()

Layout(
    content = {
        Icon(imageVector = Icons.Default.Star, contentDescription = null)
        Text(text = "Meerregelige tekst hier")
    },
    measurePolicy = { measurables, constraints ->
        val textMeasurable = measurables[1]
        val textPlaceable = textMeasurable.measure(constraints)
        val iconPlaceable = measurables[0].measure(constraints)

        val firstLineHeight = textMeasurer.measure(
            text = "Sample",
            style = MaterialTheme.typography.bodyMedium,
            constraints = Constraints(maxWidth = 2000, maxHeight = 100)
        ).size.height

        layout(width = textPlaceable.width + iconPlaceable.width,
               height = maxOf(textPlaceable.height, iconPlaceable.height)) {
            iconPlaceable.placeRelative(0, (firstLineHeight - iconPlaceable.height) / 2)
            textPlaceable.placeRelative(iconPlaceable.width, 0)
        }
    }
)

In dit voorbeeld bepaalt het meten van de eerste regel via TextMeasurer de positie van het pictogram. Zonder TextMeasurer zou het pictogram worden gecentreerd over de volledige hoogte van de meerregelige tekst, wat visueel onjuist is. Dit patroon wordt veel gebruikt in chats, contactlijsten en informatiekaarten.

Prestatietips

TextMeasurer — is een synchrone API die in de UI-thread werkt. Bij overmatig gebruik kan het framedrops veroorzaken, vooral bij het meten van grote hoeveelheden tekst op zwakkere apparaten.

Eerste regel — cache het resultaat. Wikkel de aanroep van measure() altijd in remember met afhankelijkheden van tekst en stijl. Roep measure() nooit aan binnen CompositionLocal of in hete recompositiepaden.

Tweede regel — beperk maxWidth en maxHeight. Als u maxWidth = Constraints.Infinity instelt, kan TextMeasurer geen regels teruglopen en zal de tekst buiten het scherm vallen. Geef altijd realistische beperkingen door, vooral voor meerregelige tekst.

Derde — vermijd herhaalde meting met dezelfde parameters. Als tekst en stijl niet zijn veranderd, is het resultaat van measure() hetzelfde. Combineer meting met Deferred of LaunchedEffect voor asynchrone scenario's.

Veelgestelde vragen

Waarin verschilt TextMeasurer van onSizeChanged in Compose?

TextMeasurer meet tekst vóór het renderen, terwijl onSizeChanged erna meet. TextMeasurer is nodig wanneer de tekstgrootte de lay-out van de ouder beïnvloedt; onSizeChanged is geschikt voor reactieve logica na compositie.

Kan SpannableString worden gemeten via TextMeasurer?

Ja, TextMeasurer.measure() accepteert AnnotatedString, die SpannableString met inline-stijlen, links en kleuren omvat. Alle spans worden in aanmerking genomen bij het meten.

Waarom retourneert TextMeasurer afmetingen in pixels en niet in dp?

TextMeasurer werkt op het niveau van Skia-rendering, waar alle afmetingen in pixels zijn. Converteer via LocalDensity.current: density.run { width.toDp() }.

Hoe meet ik tekst voordat het lettertype is geladen?

TextMeasurer gebruikt FontFamily.Default tot het laden van het aangepaste lettertype. Wacht voor nauwkeurige meting op het laden via FontResource en gebruik async/await.

Beïnvloedt TextMeasurer de prestaties van LazyColumn-lijsten?

Het meten van tekst in elk element van LazyColumn kan de FPS op zwakkere apparaten verlagen. Optimalisatie: cache het resultaat via remember en beperk de tekstgrootte.

Samenvatting

  • TextMeasurer — Compose-API voor het meten van tekst vóór het renderen, retourneert TextLayoutResult.
  • De methode measure() ontvangt tekst, stijl en Constraints in pixels.
  • De instantie wordt gemaakt via rememberTextMeasurer() en hergebruikt.
  • Voor éénregelige tekst wordt het resultaat gebruikt voor adaptieve containerbreedte.
  • Voor meerregelige tekst — lineCount, getLineWidth() en getBoundingBox() geven een volledig beeld.
  • In aangepaste Layouts stelt TextMeasurer u in staat elementen uit te lijnen op de eerste regel tekst.
  • Cache het resultaat via remember en vermijd meten in hete recompositiepaden.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook