Jedna z zasad Compose mówi, że dzieci należy mierzyć tylko raz. Dwukrotne zmierzenie dzieci powoduje wyjątek w czasie działania. Czasami jednak przed zmierzeniem dzieci potrzebujesz pewnych informacji na ich temat.
Intrinsics umożliwia wysyłanie zapytań dotyczących dzieci, zanim zostaną one zmierzone.
W przypadku funkcji kompozycyjnej możesz poprosić o jej IntrinsicSize.Min
lub IntrinsicSize.Max
:
Modifier.width(IntrinsicSize.Min)
– jaka jest minimalna szerokość, która umożliwia prawidłowe wyświetlanie treści?Modifier.width(IntrinsicSize.Max)
– Jaka jest maksymalna szerokość, której potrzebujesz, aby prawidłowo wyświetlać treści?Modifier.height(IntrinsicSize.Min)
– Jaka jest minimalna wysokość potrzebna do prawidłowego wyświetlania treści?Modifier.height(IntrinsicSize.Max)
– Jaka jest maksymalna wysokość, której potrzebujesz, aby prawidłowo wyświetlać treści?
Jeśli na przykład w układzie niestandardowym zapytasz o minIntrinsicHeight
elementu Text
z ograniczeniami width
, zwróci on height
elementu Text
z tekstem narysowanym w jednym wierszu.
Funkcje pierwotne w praktyce
Możesz utworzyć komponent, który wyświetla na ekranie 2 teksty oddzielone separatorem:
Aby to zrobić, użyj elementu Row
z 2 komponentami Text
, które wypełniają dostępną przestrzeń, oraz elementu Divider
pośrodku. Element Divider
powinien być tak wysoki jak najwyższy element Text
i cienki (width = 1.dp
).
@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 ) } }
Element Divider
rozszerza się na cały ekran, co nie jest pożądanym zachowaniem:
Dzieje się tak, ponieważ Row
mierzy każde dziecko osobno, a wysokość Text
nie może być używana do ograniczania Divider
.
Aby element Divider
wypełniał dostępne miejsce o określonej wysokości, użyj modyfikatora height(IntrinsicSize.Min)
.
height(IntrinsicSize.Min)
dostosowuje wysokość elementów podrzędnych do ich minimalnej wysokości wewnętrznej. Ten modyfikator jest rekurencyjny, więc wysyła zapytanie o minIntrinsicHeight
Row
i jego elementów podrzędnych.
Zastosowanie tego modyfikatora do kodu sprawi, że będzie on działać zgodnie z oczekiwaniami:
@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") } } }
Z podglądem:
Wysokość elementu Row
jest określana w ten sposób:
- Wartość
minIntrinsicHeight
elementu kompozycyjnegoRow
jest maksymalną wartościąminIntrinsicHeight
jego elementów podrzędnych. - Wartość
minIntrinsicHeight
elementuDivider
wynosi 0, ponieważ nie zajmuje on miejsca, jeśli nie podano żadnych ograniczeń. - Wartość
Text
minIntrinsicHeight
to wartość tekstu dla konkretnego elementuwidth
. - Dlatego ograniczenie
height
elementuRow
staje się maksymalną wartościąminIntrinsicHeight
elementówText
. - Wtedy
Divider
rozszerza swójheight
do ograniczeniaheight
podanego przezRow
.
Wartości wewnętrzne w układach niestandardowych
Podczas tworzenia niestandardowego modyfikatora Layout
lub layout
pomiary wewnętrzne są obliczane automatycznie na podstawie przybliżeń. Dlatego obliczenia mogą nie być prawidłowe w przypadku wszystkich układów. Te interfejsy API oferują opcje zastępowania tych ustawień domyślnych.
Aby określić pomiary wewnętrzne niestandardowego Layout
, podczas jego tworzenia zastąp wartości minIntrinsicWidth
, minIntrinsicHeight
, maxIntrinsicWidth
i maxIntrinsicHeight
interfejsu MeasurePolicy
.
@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. } ) }
Podczas tworzenia niestandardowego modyfikatora layout
zastąp powiązane metody w interfejsie LayoutModifier
.
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. }
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony.
- Układy niestandardowe {:#custom-layouts}
- Linie wyrównania w Jetpack Compose
- Etapy Jetpack Compose