Compose'un kurallarından biri, çocuklarınızı yalnızca bir kez ölçmeniz gerektiğidir. Çocukları iki kez ölçmek, çalışma zamanı istisnası oluşturur. Ancak, çocuklarınızın ölçülerini almadan önce haklarında bilgi edinmeniz gereken durumlar 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östermek 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
öğesinin minIntrinsicHeight
özelliğini sorarsanız metnin tek bir satırda çizildiği Text
öğesinin height
özelliğini döndürür.
Yerleşik özelliklerin kullanımı
Ekranda iki metni aşağıdaki gibi bir ayırıcıyla ayırarak gösteren bir composable oluşturmak istediğimizi düşünelim:
Bunu nasıl yapabiliriz? İçinde iki Text
bulunan ve olabildiğince genişleyen bir Row
ile ortada bir Divider
olabilir. 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 ) } }
Bunu önizlediğimizde Divider
öğesinin tüm ekranı kapladığını görüyoruz. Bu, istediğimiz bir durum değil:
Bunun nedeni, Row
her alt öğeyi ayrı ayrı ölçtüğü ve Text
yüksekliğinin Divider
öğesini sınırlamak 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)
, alt öğelerini minimum doğal yükseklikleri kadar yüksek olmaya zorlar. Özyinelemeli olduğundan Row
ve alt öğeleri minIntrinsicHeight
sorgulanır.
Bunu kodumuza uyguladığımızda 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
composable'ın minIntrinsicHeight
değeri, alt öğelerinin minIntrinsicHeight
değerinin maksimumu olur. Divider
öğesinin minIntrinsicHeight
değeri 0'dır. Çünkü kısıtlama verilmediğinde alan kaplamaz. Text
minIntrinsicHeight
değeri ise belirli bir width
değeri verilen metnin değeri olur. Bu nedenle, Row
öğesinin height
kısıtlaması, Text
değerlerinin maksimum minIntrinsicHeight
değeri olur. Divider
, Row
tarafından verilen height
kısıtlamasıyla height
değerini genişletir.
Özel düzenlerinizdeki dahili öğeler
Özel bir Layout
veya layout
değiştiricisi 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.
@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ı