Jedną z reguł tworzenia wiadomości jest, aby dzieci zliczały się tylko raz; dwa razy powoduje wystąpienie wyjątku w czasie działania. Jednak czasami przed dokonaniem pomiarów potrzebujesz informacji o swoich dzieciach.
Intrinsics umożliwia wysyłanie zapytań do dzieci, zanim zostaną one zmierzone.
Do funkcji kompozycyjnej możesz poprosić o intrinsicWidth
lub intrinsicHeight
:
(min|max)IntrinsicWidth
: Jaka jest minimalna/maksymalna szerokość przy tej wysokości, jaką można pomalować treści?(min|max)IntrinsicHeight
: Przy tej szerokości jaka jest minimalna/maksymalna wysokość, na jaką możesz prawidłowo pomalować treści?
Jeśli na przykład zapytasz o minIntrinsicHeight
elementu Text
z nieskończonym width
, otrzymasz height
z metody Text
, tak jakby tekst był narysowany w jednej linii.
Cechy wewnętrzne w praktyce
Wyobraź sobie, że chcemy utworzyć kompozycję, która wyświetla na ekranie 2 teksty oddzielone separatorem w ten sposób:
Jak to zrobić? Możemy mieć obiekt Row
z 2 elementami Text
w środku, który się rozwija oraz Divider
w środku. Chcemy, aby element Divider
miał taką samą wysokość, jak największy 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 ) Divider( color = Color.Black, modifier = Modifier.fillMaxHeight().width(1.dp) ) Text( modifier = Modifier .weight(1f) .padding(end = 4.dp) .wrapContentWidth(Alignment.End), text = text2 ) } }
Gdy wyświetlimy podgląd, zobaczysz, że Divider
rozwija się na cały ekran, a to nie jest potrzebne:
Dzieje się tak, ponieważ Row
mierzy każdy element podrzędny oddzielnie, a wysokości Text
nie można wykorzystać do ograniczenia elementu Divider
. Divider
ma wypełniać dostępną przestrzeń o danej wysokości. Do tego możemy użyć modyfikatora height(IntrinsicSize.Min)
.
W height(IntrinsicSize.Min)
rozmiar dziecka musi być taki sam jak jego minimalna wysokość. Jest rekurencyjny, więc wysyła zapytanie Row
i jego elementy podrzędne minIntrinsicHeight
.
Jeśli zastosujesz go do naszego kodu, będzie to 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 ) 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") } } }
W przypadku podglądu:
minIntrinsicHeight
elementu kompozycyjnego Row
będzie stanowić maksymalną liczbę minIntrinsicHeight
elementów podrzędnych. Wartość minIntrinsicHeight
elementu Divider
ma wartość 0, ponieważ nie zajmuje ona miejsca, jeśli nie ma żadnych ograniczeń. Pole „Text
minIntrinsicHeight
” będzie zawierać tekst z określonym parametrem width
. Dlatego ograniczenie height
elementu Row
będzie wartością maksymalną minIntrinsicHeight
z Text
s. Divider
rozwinie się wtedy height
do ograniczenia height
podanego przez Row
.
Elementy wewnętrzne w układach niestandardowych
Przy tworzeniu niestandardowego modyfikatora Layout
lub layout
pomiary wewnętrzne są obliczane automatycznie na podstawie przybliżeń. Dlatego też obliczenia mogą nie być poprawne w przypadku niektórych układów. Te interfejsy API oferują opcje zastępowania tych wartości domyślnych.
Aby określić własne pomiary niestandardowego interfejsu Layout
, zastąp minIntrinsicWidth
, minIntrinsicHeight
, maxIntrinsicWidth
i maxIntrinsicHeight
interfejsu MeasurePolicy
podczas jego tworzenia.
@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