Compose'un kurallarından biri, alt öğelerinizi yalnızca bir kez ölçmeniz gerektiğidir. Alt öğeleri iki kez ölçmek, çalışma zamanı istisnası oluşturur. Ancak, ölçüm yapmadan önce çocuklarınız hakkında bazı bilgilere ihtiyacınız olabilir.
Intrinsics, çocuklar ölçülmeden önce onlarla ilgili sorgu yapmanıza olanak tanır.
Bir composable'ın IntrinsicSize.Min veya IntrinsicSize.Max değerini isteyebilirsiniz:
Modifier.width(IntrinsicSize.Min)- İçeriğinizi düzgün şekilde görüntülemek için gereken minimum genişlik nedir?Modifier.width(IntrinsicSize.Max)- İçeriğinizi düzgün şekilde görüntülemek için gereken maksimum genişlik nedir?Modifier.height(IntrinsicSize.Min)- İçeriğinizi düzgün şekilde göstermek için gereken minimum yükseklik nedir?Modifier.height(IntrinsicSize.Max)- İçeriğinizi düzgün şekilde göstermek için gereken maksimum yükseklik nedir?
Örneğin, özel bir düzende sonsuz width kısıtlaması olan bir Text'nin minIntrinsicHeight'sını sorarsanız metnin tek bir satırda çizildiği Text'nin height'ını döndürür.
Yerleşik özelliklerin kullanımı
Ekranda iki metni ayırıcıyla ayrılmış şekilde gösteren bir composable oluşturabilirsiniz:
Bunu yapmak için, kullanılabilir alanı dolduran iki Text composable'ı ve ortada bir Divider içeren bir Row kullanın. Divider, en uzun Text kadar uzun ve ince (width = 1.dp) olmalıdır.
@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 ) VerticalDivider( color = Color.Black, modifier = Modifier.fillMaxHeight().width(1.dp) ) Text( modifier = Modifier .weight(1f) .padding(end = 4.dp) .wrapContentWidth(Alignment.End), text = text2 ) } }
Divider, istenen davranış olmamasına rağmen tüm ekrana genişliyor:
Bunun nedeni, Row her çocuğu ayrı ayrı ölçtüğü ve Text yüksekliğinin Divider için sınırlama olarak kullanılamamasıdır.
Divider öğesinin, kullanılabilir alanı belirli bir yükseklikle doldurmasını istiyorsanız bunun yerine height(IntrinsicSize.Min) değiştiricisini kullanın.
height(IntrinsicSize.Min), alt öğelerini minimum doğal yükseklikleri kadar yüksek olacak şekilde boyutlandırır. Bu değiştirici yinelemeli olduğundan Row ve alt öğelerinin minIntrinsicHeight sorgusunu yapar.
Bu değiştiriciyi kodunuza uyguladığınızda kodunuz beklendiği gibi çalışı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 ) VerticalDivider( 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") } } }
Önizlemeli:
Row yüksekliği aşağıdaki şekilde belirlenir:
Rowcomposable'ınminIntrinsicHeightdeğeri, alt öğelerinin maksimumminIntrinsicHeightdeğeridir.- Kısıtlama verilmediği için alan kaplamadığından
DivideröğesininminIntrinsicHeightdeğeri 0'dır. TextminIntrinsicHeight, belirli birwidthiçin metnin 'idir.- Bu nedenle,
Rowöğesininheightkısıtlaması,Textöğelerinin maksimumminIntrinsicHeightdeğeri olur. Divider,Rowtarafından verilenheightkısıtlamasına göreheightdeğerini genişletir.
Özel düzenlerinizdeki yerleşik özellikler
Özel bir Layout veya layout değiştirici oluştururken, yaklaşık değerlere göre otomatik olarak içsel ölçümler 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 öğenizin yerleşik özellik ölçülerini 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. }
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ı