Compose'un kurallarından biri, alt öğeleri yalnızca bir kez ölçmenizdir. Alt öğeleri iki kez ölçmek, çalışma zamanı istisnasına yol açar. Bununla birlikte, çocuklarınızı ölçmeden önce bazı bilgilere ihtiyaç duyduğunuz zamanlar olabilir.
Doğal nitelik, çocukları gerçekte ölçülmeden önce sorgulamanızı sağlar.
Bir composable için intrinsicWidth
veya intrinsicHeight
isteyebilirsiniz:
(min|max)IntrinsicWidth
: Bu genişliğe göre, içeriğinizi düzgün şekilde boyayabileceğiniz minimum/maksimum genişlik nedir?(min|max)IntrinsicHeight
: Bu yükseklik göz önüne alındığında, içeriğinizi düzgün şekilde boyayabileceğiniz minimum/maksimum yükseklik nedir?
Örneğin, sonsuz height
içeren bir Text
öğesinin minIntrinsicHeight
özelliğini sorarsanız Text
öğesinin height
değerini, metin tek bir satıra çizilmiş gibi döndürür.
Yerleşik özellikleri uygulama
Ekranda iki metni şu şekilde bir ayırıcıyla ayrılmış olarak gösteren bir composable oluşturmak istediğimizi hayal edin:
Bunu nasıl yapabiliriz? İçinde mümkün olduğunca geniş olan iki Text
ve ortasında bir Divider
bulunan bir Row
olabilir. Divider
öğesinin, en uzun Text
ve ince (width = 1.dp
) kadar uzun olmasını istiyoruz.
@Composable fun TwoTexts(modifier: Modifier = Modifier, text1: String, text2: String) { Row(modifier = modifier) { Text( modifier = Modifier .weight(1f) .padding(start = 4.dp) .wrapContentWidth(Alignment.Start), text = text1 ) Divider( color = Color.Black, modifier = Modifier.fillMaxHeight().width(1.dp) ) Text( modifier = Modifier .weight(1f) .padding(end = 4.dp) .wrapContentWidth(Alignment.End), text = text2 ) } }
Bunu önizlersek Divider
öğesinin tüm ekrana genişlediğini görürüz ve bizim istediğimiz bu değildir:
Bunun nedeni, Row
ürününün her bir alt öğeyi ayrı ayrı ölçmesi ve Text
yüksekliğinin Divider
kısıtlaması için kullanılamamasıdır. Divider
öğesinin, kullanılabilir alanı belirli bir
yükseklikle doldurmasını istiyoruz. Bunun için height(IntrinsicSize.Min)
değiştiriciyi kullanabiliriz .
height(IntrinsicSize.Min)
, çocuklarının doğal boylarını aşmaya zorlanır. Yinelemeli olduğundan Row
ve alt öğelerini (minIntrinsicHeight
) sorgular.
Bu kodu kodumuza uyguladığınızda, beklendiği gibi çalışacaktır:
@Composable fun TwoTexts(modifier: Modifier = Modifier, text1: String, text2: String) { Row(modifier = modifier.height(IntrinsicSize.Min)) { Text( modifier = Modifier .weight(1f) .padding(start = 4.dp) .wrapContentWidth(Alignment.Start), text = text1 ) Divider( color = Color.Black, modifier = Modifier.fillMaxHeight().width(1.dp) ) Text( modifier = Modifier .weight(1f) .padding(end = 4.dp) .wrapContentWidth(Alignment.End), text = text2 ) } } // @Preview @Composable fun TwoTextsPreview() { MaterialTheme { Surface { TwoTexts(text1 = "Hi", text2 = "there") } } }
Önizlemeyle:
Row
composable'ın minIntrinsicHeight
, alt öğelerinin maksimum
minIntrinsicHeight
tanesi olacak. Divider
öğesinin minIntrinsicHeight
değeri, herhangi bir kısıtlama sağlanmadığında yer kaplamadığı için 0 olur. Text
minIntrinsicHeight
değeri, belirli bir width
belirtilen metin olur. Bu nedenle, Row
öğesinin height
kısıtlaması, Text
için maksimum minIntrinsicHeight
olacaktır. Daha sonra Divider
, height
değerini Row
tarafından sağlanan height
kısıtlamasına genişletir.
Özel düzenlarınızdaki iç öğeler
Özel Layout
veya layout
değiştiricisi oluşturulurken doğal ölçümler yaklaşık değerlere göre otomatik olarak hesaplanır. Bu nedenle, hesaplamalar tüm düzenlerde doğru olmayabilir. Bu API'ler, bu varsayılanları geçersiz kılma seçenekleri sunar.
Özel Layout
'inizin yerleşik ölçümlerini belirtmek için arayüz oluştururken MeasurePolicy
arayüzünün minIntrinsicWidth
, minIntrinsicHeight
, maxIntrinsicWidth
ve maxIntrinsicHeight
değerlerini geçersiz kılın.
@Composable fun MyCustomComposable( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( content = content, modifier = modifier, measurePolicy = object : MeasurePolicy { override fun MeasureScope.measure( measurables: List<Measurable>, constraints: Constraints ): MeasureResult { // Measure and layout here // ... } override fun IntrinsicMeasureScope.minIntrinsicWidth( measurables: List<IntrinsicMeasurable>, height: Int ): Int { // Logic here // ... } // Other intrinsics related methods have a default value, // you can override only the methods that you need. } ) }
Özel layout
değiştiricinizi oluştururken LayoutModifier
arayüzündeki ilgili yöntemleri geçersiz kılın.
fun Modifier.myCustomModifier(/* ... */) = this then object : LayoutModifier { override fun MeasureScope.measure( measurable: Measurable, constraints: Constraints ): MeasureResult { // Measure and layout here // ... } override fun IntrinsicMeasureScope.minIntrinsicWidth( measurable: IntrinsicMeasurable, height: Int ): Int { // Logic here // ... } // Other intrinsics related methods have a default value, // you can override only the methods that you need. }
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Özel düzenler {:#custom-layouts }
- Jetpack Compose'da hizalama çizgileri
- Jetpack Compose Aşamaları