TextMeasurer: Nedir ve Compose’da Metin Ölçümü Nasıl Çalışır

Yazar: IT Sectr Yayınlanma: 2026-07-25 Okuma süresi: 8 dk

TextMeasurer, metnin ekranda gerçekten oluşturulmasından önce boyutlarını ölçmek için tasarlanmış bir Jetpack Compose API’sidir. Android View’daki Paint.measureText aracılığıyla klasik yaklaşımın aksine, TextMeasurer stil ve kısıtlamaları dikkate alarak genişlik, yükseklik ve satır metriklerini elde etmek için Compose-native bir yol sağlar. Android Developers Documentation’a (2025) göre TextMeasurer, metin boyutunun diğer öğelerin konumlandırılmasını etkilediği özel Layout bileşenlerinde, animasyonlu etiketlerde ve uyarlanabilir UI öğelerinde aktif olarak kullanılmaktadır.

Ana Noktalar

  • TextMeasurer — Oluşturma öncesinde metin ölçmek için bir Compose API’si.
  • measure() metodu, satır ve karakter metrikleriyle TextLayoutResult döndürür.
  • API, stil, yazı tipi, boyut ve piksel cinsinden kap kısıtlamalarını dikkate alır.
  • TextMeasurer, tek satırlık ve çok satırlı metin ölçümünü destekler.
  • Ölçüm sonucu özel düzen ve metin animasyonu için kullanılır.

Jetpack Compose’da TextMeasurer Nedir?

TextMeasurer, androidx.compose.ui.text paketinden gelen işlevsel bir arayüz olup, Compose’da metni ekranda gerçekten oluşturmadan ölçmeye olanak tanır. Compose metin motorunun bir parçasıdır ve işleme için Skia kullanan Paragraph API düzeyinde çalışır.

TextMeasurer’ın temel amacı ön ölçümdür. Compose’da metin boyutu genellikle Composable Layout’a yerleştirildikten sonra belirlenir. Ancak, düzenlemeden önce metin genişliğini bilmeniz gereken senaryolar vardır — örneğin, bir dizenin bir kaba sığıp sığmadığına karar vermek veya metin uzunluğuna göre bir düğmenin boyutunu hesaplamak için.

TextMeasurer, bir TextMeasureRequest (metin, stil, kısıtlamalar) alan ve TextLayoutResult (metrikler, satırlar, karakterler) döndüren measure() metodunu sağlayarak bunu çözer. Bu, geliştiricinin tüm metin verilerini tek kare gecikme olmadan eşzamanlı olarak almasına olanak tanır.

Metin boyutunun ana bileşen boyutunu etkilediği durumlarda, animasyonlu metin geçişleri oluştururken veya metnin diğer öğelerle bir arada bulunduğu özel Layout’lar uygularken TextMeasurer’ı kullanın.

TextMeasurer Nasıl Çalışır

TextMeasurer API’si iki temel varlıktan oluşur: rememberTextMeasurer() (örnek oluşturma) ve measure() (ölçümü çalıştırma). Örnek, bileşenin tüm yaşam döngüsü için bir kez oluşturulur ve tüm ölçümler için yeniden kullanılır.

kotlin
val textMeasurer = rememberTextMeasurer()

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

// result.size.width, result.size.height, result.lineCount

constraints parametresi, metnin sığması gereken maksimum genişlik ve yüksekliği tanımlar. Metin genişliğe sığmazsa, bir sonraki satıra kaydırılır. Ölçüm sonucu, satır sayısını, her karakterin konumunu, her satırın genişliğini ve genel metin boyutunu sağlayan bir TextLayoutResult içerir.

TextMeasurer, UI iş parçacığında eşzamanlı olarak çalışır ve yeniden oluşturmayı tetiklemez. Ancak, farklı stillerle sık sık metin ölçümü yük oluşturabilir — bu nedenle örnek remember aracılığıyla oluşturulur ve yeniden kullanılır.

Tek Satırlık Metin Ölçümü

En basit senaryo, ana kabın boyutunu belirlemek için tek satırlık metnin genişliğini ölçmektir. Örneğin, genişliği etiketin uzunluğuna bağlı olan bir düğme için.

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)
}

Bu örnekte, remember(label) ölçümün yalnızca metin değiştiğinde yeniden başlamasını sağlar. Satır kaydırmayı önlemek için kısıtlamalar büyük bir maxWidth (1000) ile ayarlanır — gerçek kısıtlama metin genişliğine eşit olacaktır. Box genişliği, ölçülen metin genişliğine ayarlanır ve “metne göre boyutlandırılmış düğme” efekti elde edilir.

Not: sonuçtaki genişlik .dp kullanılarak dp’ye dönüştürülmelidir, çünkü TextMeasurer boyutları piksel cinsinden döndürürken Modifier.width Dp bekler. Doğruluk için density ve LocalDensity.current kullanın.

Çok Satırlı Metin Ölçümü

Çok satırlı metin için TextMeasurer, yalnızca toplam yüksekliği değil, aynı zamanda satır sayısını ve paragraf içindeki her karakterin konumunu da belirlemenizi sağlar. Bu, özel metin alanları, sohbetler veya düzenleyiciler oluştururken gereklidir.

Çok satırlı metin için temel TextLayoutResult özellikleri: lineCount (satır sayısı), getLineTop(index) (satır başlangıcının Y koordinatı), getLineBottom(index) (satır sonunun Y koordinatı), getLineWidth(index) (satır genişliği). Bunları birleştirerek, arayüz öğelerini metin satırlarına göre hassas bir şekilde konumlandırabilirsiniz.

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

getLineWidth(lineIndex) metodu, belirtilen satırın genişliğini piksel cinsinden döndürür. Satır kap sınırına ulaşmazsa maxWidth’den küçük olabilir. Her satırın genişliğini bilerek, manuel olarak yaslama efekti uygulayabilir veya kısa satırların yanına satır içi öğeler yerleştirebilirsiniz.

Belirli bir karakterin konumunu almak için getBoundingBox(offset) kullanın; bu, left, top, right, bottom koordinatlarına sahip bir Rect döndürür. Bu, özel metin alanlarında imleç konumlandırma veya bir metin aralığını animasyonla vurgulamak için kullanışlıdır.

Özel Bileşenlerde TextMeasurer

TextMeasurer’ın en güçlü uygulaması, metnin diğer öğelerle bir arada bulunduğu ve boyutlarının birbirine bağlı olduğu özel Layout bileşenleridir. Örneğin, simgenin tüm blok yerine metnin ilk satırına göre ortalanması gereken bir “Simge + metin” widget’ı.

Standart bir Row’da simge, tüm Row yüksekliğine göre ortalanır; bu, metin 3 satır kaplarken simge tek satır olduğunda doğal görünmez. TextMeasurer ile ilk satırı ölçebilir ve simgeyi tam olarak ona hizalayabilirsiniz.

kotlin
val textMeasurer = rememberTextMeasurer()

Layout(
    content = {
        Icon(imageVector = Icons.Default.Star, contentDescription = null)
        Text(text = "Multi-line text here")
    },
    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)
        }
    }
)

Bu örnekte, TextMeasurer aracılığıyla ilk satırın ölçülmesi simgenin konumunu belirler. TextMeasurer olmadan simge, çok satırlı metnin tüm yüksekliğine göre ortalanır ki bu görsel olarak yanlıştır. Bu desen sohbetlerde, kişi listelerinde ve bilgi kartlarında yaygın olarak kullanılır.

Performans İpuçları

TextMeasurer, UI iş parçacığında çalışan eşzamanlı bir API’dir. Aşırı kullanımı, özellikle zayıf cihazlarda büyük metin hacimlerini ölçerken kare düşüşlerine neden olabilir.

İlk kural — sonucu önbelleğe alın. measure() çağrısını her zaman metin ve stil bağımlılıklarıyla remember içine sarın. CompositionLocal içinde veya sıcak yeniden oluşturma yollarında asla measure() çağırmayın.

İkinci kural — maxWidth ve maxHeight’i sınırlayın. maxWidth = Constraints.Infinity olarak ayarlarsanız, TextMeasurer satırları kaydıramaz ve metin ekran dışına çıkar. Özellikle çok satırlı metin için her zaman gerçekçi kısıtlamalar girin.

Üçüncü kural — aynı parametrelerle tekrarlanan ölçümden kaçının. Metin ve stil değişmediyse, measure() sonucu aynı olacaktır. Zaman uyumsuz senaryolar için ölçümü Deferred veya LaunchedEffect ile birleştirin.

Sıkça Sorulan Sorular

TextMeasurer, Compose’daki onSizeChanged’den nasıl farklıdır?

TextMeasurer metni oluşturmadan önce ölçerken, onSizeChanged sonra ölçer. TextMeasurer, metin boyutu ana düzeni etkilediğinde gereklidir; onSizeChanged, oluşturma sonrası reaktif mantık için uygundur.

SpannableString, TextMeasurer ile ölçülebilir mi?

Evet, TextMeasurer.measure(), satır içi stiller, bağlantılar ve renkler içeren SpannableString’i içeren AnnotatedString’i kabul eder. Tüm aralıklar ölçüm sırasında dikkate alınır.

TextMeasurer neden dp yerine piksel cinsinden boyut döndürür?

TextMeasurer, tüm boyutların piksel cinsinden olduğu Skia oluşturma düzeyinde çalışır. LocalDensity.current aracılığıyla dönüştürün: density.run { width.toDp() }.

Bir yazı tipi yüklenmeden önce metin nasıl ölçülür?

TextMeasurer, özel bir yazı tipi yüklenene kadar FontFamily.Default kullanır. Doğru ölçüm için, FontResource aracılığıyla yazı tipinin yüklenmesini bekleyin ve async/await kullanın.

TextMeasurer, LazyColumn listelerinin performansını etkiler mi?

Her LazyColumn öğesinde metin ölçmek, zayıf cihazlarda FPS’yi düşürebilir. Optimizasyon: remember aracılığıyla sonucu önbelleğe alın ve metin boyutunu sınırlayın.

Özet

  • TextMeasurer — Oluşturma öncesinde metin ölçmek için Compose API’si, TextLayoutResult döndürür.
  • measure() metodu, metin, stil ve Constraints’i piksel cinsinden kabul eder.
  • Örnek, rememberTextMeasurer() aracılığıyla oluşturulur ve yeniden kullanılır.
  • Tek satırlık metin için sonuç uyarlanabilir kap genişliği için kullanılır.
  • Çok satırlı metin için — lineCount, getLineWidth() ve getBoundingBox() tam resmi sağlar.
  • Özel Layout’larda TextMeasurer, öğelerin metnin ilk satırına göre hizalanmasını sağlar.
  • Sonucu remember aracılığıyla önbelleğe alın ve sıcak yeniden oluşturma yollarında ölçüm yapmaktan kaçının.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun