Oluşturma kurallarından biri, çocuklarınızı yalnızca bir kez ölçmeniz gerektiğidir. Çocukların iki kez ölçülmesi, çalışma zamanı istisnaları oluşturur. Bununla birlikte, ölçüm yapmadan önce çocuklarınızla ilgili bazı bilgilere ihtiyaç duyduğunuz zamanlar olur.
Intrinsics, çocukları gerçekten ölçülmeden önce sorgulamanıza olanak tanır.
Bir besteden intrinsicWidth
veya intrinsicHeight
isteyebilirsiniz:
(min|max)IntrinsicWidth
: Bu yükseklik dikkate alındığında, içeriğinizi düzgün bir şekilde boyayabileceğiniz minimum/maksimum genişlik ne kadardır?(min|max)IntrinsicHeight
: Bu genişlik dikkate alındığında, içeriğinizi düzgün bir şekilde boyayabileceğiniz minimum/maksimum yükseklik nedir?
Örneğin, sonsuz width
değerine sahip bir Text
öğesinin minIntrinsicHeight
sorusunu sorarsanız Text
metninin height
değerini, tek bir satır gibi çizilmiş gibi döndürür.
İçsel beceriler iş başında
Ekranda, aşağıdaki gibi bir ayırıcıyla ayrılmış iki metin gösteren bir kombinasyon oluşturmak istediğimizi varsayalım:
Bunu nasıl yapabiliriz? İçinde iki Text
bulunan ve mümkün olduğunca genişletilen bir Row
ve ortada bir Divider
bulunabilir. Bölen'in en uzun Text
ve ince (width = 1.dp
) kadar yüksek olmasını isteriz.
@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 önizlediğimizde, Ayırıcı'nın tüm ekrana genişlediğini görürüz ve istediğimiz bu değildir:
Bunun nedeni, Row
'ın her alt öğeyi ayrı olarak ölçmesi ve Text
yüksekliğinin, Divider
kısıtlaması için kullanılamamasıdır. Divider
öğesinin, mevcut alanı belirli bir yükseklikle doldurmasını istiyoruz. Bunun için height(IntrinsicSize.Min)
değiştiricisini kullanabiliriz .
height(IntrinsicSize.Min)
, çocuklarının minimum fiziksel yüksekliği kadar yüksek olmasına zorlanır. Yinelendiği için Row
ve alt öğelerini minIntrinsicHeight
sorgulayacak.
Kodun bu şekilde kullanılması, beklenen şekilde ç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
bestesinin minIntrinsicHeight
alt öğeleri maksimum minIntrinsicHeight
olacaktır. Herhangi bir kısıtlama sağlanmazsa Divider
öğesinin minIntrinsicHeight
değeri 0 olur; Text
minIntrinsicHeight
, belirli bir width
verilen metnin minIntrinsicHeight
değeri olur. Bu nedenle, Row
öğesinin height
kısıtlaması, Text
öğesinin maksimum minIntrinsicHeight
değerini alır. Ardından Divider
, height
özelliğini Row
tarafından sağlanan height
kısıtlamasına genişletir.
Özel düzenlerinizdeki içsel bilgiler
Özel bir Layout
veya layout
değiştiricisi oluşturulurken iç ölçümler, yaklaşık değerler temel alınarak otomatik olarak hesaplanır. Bu nedenle, hesaplamalar tüm düzenler için doğru olmayabilir. Bu API'ler, bu varsayılanları geçersiz kılma seçenekleri sunar.
Özel Layout
metriğinizin iç mekan ölçümlerini belirtmek için, 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. }