W Compose możesz łączyć ze sobą wiele modyfikatorów, aby zmieniać wygląd i styl funkcji kompozycyjnych. Te łańcuchy modyfikatorów mogą wpływać na ograniczenia przekazywane do funkcji kompozycyjnych, które określają granice szerokości i wysokości.
Na tej stronie opisujemy, jak połączone modyfikatory wpływają na ograniczenia, a w konsekwencji na pomiar i umieszczanie funkcji kompozycyjnych.
Modyfikatory w drzewie iUI
Aby zrozumieć, jak modyfikatory wpływają na siebie nawzajem, warto wyobrazić sobie, jak wyglądają w drzewie UI, które jest generowane w fazie kompozycji. Więcej informacji znajdziesz w sekcji Kompozycja.
W drzewie UI możesz wizualizować modyfikatory jako węzły opakowujące węzły układu:

Dodanie do funkcji kompozycyjnej więcej niż jednego modyfikatora powoduje utworzenie łańcucha modyfikatorów. Gdy połączysz ze sobą wiele modyfikatorów, każdy węzeł modyfikatora otacza pozostałą część łańcucha i węzeł układu. Na przykład, gdy połączysz modyfikatory clip
i size
, węzeł modyfikatora clip
otoczy węzeł modyfikatora size
, który z kolei otoczy węzeł układu Image
.
W fazie układu algorytm przechodzący przez drzewo pozostaje taki sam, ale odwiedzany jest też każdy węzeł modyfikatora. W ten sposób modyfikator może zmieniać wymagania dotyczące rozmiaru i umiejscowienia modyfikatora lub węzła układu, który otacza.
Jak pokazano na rysunku 2, implementacja funkcji kompozycyjnych Image
i Text
składa się z łańcucha modyfikatorów otaczających pojedynczy węzeł układu. Implementacje elementów Row
i Column
to po prostu węzły układu, które opisują sposób rozmieszczenia elementów podrzędnych.

Podsumowując:
- Modyfikatory otaczają pojedynczy modyfikator lub węzeł układu.
- Węzły układu mogą rozmieszczać wiele węzłów podrzędnych.
W sekcjach poniżej opisujemy, jak używać tego modelu myślowego do wnioskowania o połączeniu modyfikatorów i jak wpływa ono na rozmiar funkcji kompozycyjnych.
Ograniczenia w fazie układu
Faza układu przebiega zgodnie z 3-etapowym algorytmem, który określa szerokość, wysokość oraz współrzędne x i y każdego węzła układu:
- Mierzenie elementów podrzędnych: węzeł mierzy swoje węzły podrzędne, jeśli takie istnieją.
- Określanie własnego rozmiaru: na podstawie tych pomiarów węzeł określa własny rozmiar.
- Umieszczanie elementów podrzędnych: każdy węzeł podrzędny jest umieszczany względem własnej pozycji węzła.
Constraints
pomagają znaleźć odpowiednie rozmiary węzłów w pierwszych 2 krokach algorytmu. Ograniczenia określają minimalną i maksymalną szerokość oraz wysokość węzła. Gdy węzeł określi swój rozmiar, jego zmierzony rozmiar powinien mieścić się w tym zakresie.
Rodzaje ograniczeń
Ograniczenie może należeć do jednej z tych kategorii:
- Określone: węzeł ma maksymalną i minimalną szerokość oraz wysokość.

- Nieokreślone: węzeł nie jest ograniczony żadnym rozmiarem. Maksymalna szerokość i wysokość są ustawione na nieskończoność.

- Dokładne: węzeł ma spełnić dokładne wymagania dotyczące rozmiaru. Minimalne i maksymalne granice mają tę samą wartość.

- Kombinacja: węzeł podlega kombinacji powyższych typów ograniczeń. Na przykład ograniczenie może określać szerokość, ale pozwalać na nieograniczoną maksymalną wysokość lub określać dokładną szerokość, ale zapewniać ograniczoną wysokość.

W następnej sekcji opisujemy, jak te ograniczenia są przekazywane z elementu nadrzędnego do elementu podrzędnego.
Jak ograniczenia są przekazywane z elementu nadrzędnego do podrzędnego
W pierwszym kroku algorytmu opisanego w sekcji Ograniczenia w fazie układu ograniczenia są przekazywane z elementu nadrzędnego do podrzędnego w drzewie UI.
Gdy węzeł nadrzędny mierzy swoje węzły podrzędne, przekazuje im te ograniczenia, aby poinformować je, jak duże lub małe mogą być. Następnie, gdy określa swój rozmiar, przestrzega też ograniczeń przekazanych przez jego elementy nadrzędne.
Ogólnie algorytm działa w ten sposób:
- Aby określić rozmiar, który ma zajmować, węzeł główny w drzewie UI mierzy swoje elementy podrzędne i przekazuje te same ograniczenia do pierwszego elementu podrzędnego.
- Jeśli element podrzędny jest modyfikatorem, który nie ma wpływu na pomiar, przekazuje ograniczenia do następnego modyfikatora. Ograniczenia są przekazywane w łańcuchu modyfikatorów w niezmienionej postaci, chyba że zostanie osiągnięty modyfikator, który ma wpływ na pomiary. Ograniczenia są następnie odpowiednio zmieniane.
- Gdy węzeł nie ma węzłów podrzędnych (nazywa się go „węzłem liściowym”), określa swój rozmiar na podstawie przekazanych ograniczeń i zwraca ten rozmiar do węzła nadrzędnego.
- Element nadrzędny dostosowuje swoje ograniczenia na podstawie pomiarów elementu podrzędnego i wywołuje kolejny element podrzędny z tymi dostosowanymi ograniczeniami.
- Gdy wszystkie węzły podrzędne węzła nadrzędnego zostaną zmierzone, węzeł nadrzędny określa swój rozmiar i przekazuje go do swojego węzła nadrzędnego.
- Dzięki temu całe drzewo jest przeszukiwane w głąb. W końcu wszystkie węzły ustalą swoje rozmiary i etap pomiaru zostanie zakończony.
Szczegółowy przykład znajdziesz w filmie Constraints and modifier order (Ograniczenia i kolejność modyfikatorów).
Modyfikatory wpływające na ograniczenia
W poprzedniej sekcji dowiedzieliśmy się, że niektóre modyfikatory mogą wpływać na rozmiar ograniczenia. W sekcjach poniżej opisujemy konkretne modyfikatory, które wpływają na ograniczenia.
Modyfikator size
Modyfikator size
deklaruje preferowany rozmiar treści.
Na przykład to drzewo UI powinno być renderowane w kontenerze 300dp
przez 200dp
. Ograniczenia są okreśłone, co pozwala na szerokość od 100dp
do 300dp
i wysokość od 100dp
do 200dp
:

Modyfikator size
dostosowuje przychodzące ograniczenia do wartości, która jest do niego przekazywana.
W tym przykładzie wartość to 150dp
:

size
dostosowuje ograniczenia do 150dp
.Jeśli szerokość i wysokość są mniejsze niż najmniejsze ograniczenie lub większe niż największe ograniczenie, modyfikator dopasowuje przekazane ograniczenia tak ściśle, jak to możliwe, przy jednoczesnym zachowaniu przekazanych ograniczeń:

size
, który w jak największym stopniu dostosowuje się do przekazanego ograniczenia.Pamiętaj, że łączenie kilku modyfikatorów size
nie działa. Pierwszy modyfikator size
ustawia zarówno minimalne, jak i maksymalne ograniczenia na stałą wartość. Nawet jeśli drugi modyfikator rozmiaru zażąda mniejszego lub większego rozmiaru, musi on nadal mieścić się w dokładnych przekazanych granicach, więc nie zastąpi tych wartości:

size
, w którym druga przekazana wartość (50dp
) nie zastępuje pierwszej wartości (100dp
).Modyfikator requiredSize
Jeśli chcesz, aby węzeł zastępował przychodzące ograniczenia, użyj modyfikatora requiredSize
zamiast size
. Modyfikator requiredSize
zastępuje przychodzące ograniczenia i przekazuje określony przez Ciebie rozmiar jako dokładne granice.
Gdy rozmiar zostanie przekazany z powrotem w górę drzewa, węzeł podrzędny zostanie wyśrodkowany w dostępnej przestrzeni:

requiredSize
zastępuje przychodzące ograniczenia z modyfikatora size
.Modyfikatory width
i height
Modyfikator size
dostosowuje zarówno szerokość, jak i wysokość ograniczeń. Za pomocą modyfikatorawidth
możesz ustawić stałą szerokość, ale pozostawić wysokość nieokreśloną.
Podobnie za pomocą modyfikatora height
możesz ustawić stałą wysokość, ale pozostawić szerokość nieokreśloną:

width
i modyfikator height
ustawiają odpowiednio stałą szerokość i wysokość.Modyfikator sizeIn
Modyfikator sizeIn
umożliwia ustawienie dokładnych minimalnych i maksymalnych ograniczeń szerokości i wysokości. Użyj modyfikatora sizeIn
, jeśli potrzebujesz precyzyjnej kontroli nad ograniczeniami.

sizeIn
z ustawionymi wartościami minWidth
, maxWidth
, minHeight
i maxHeight
.Przykłady
W tej sekcji znajdziesz dane wyjściowe z kilku fragmentów kodu z połączonymi modyfikatorami oraz ich wyjaśnienie.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
Ten fragment kodu generuje te dane wyjściowe:
- Modyfikator
fillMaxSize
zmienia ograniczenia, aby ustawić zarówno minimalną szerokość, jak i wysokość na wartość maksymalną –300dp
w przypadku szerokości i200dp
w przypadku wysokości. - Mimo że modyfikator
size
chce użyć rozmiaru50dp
, musi nadal przestrzegać przychodzących ograniczeń minimalnych. Modyfikatorsize
zwróci też dokładne granice ograniczeń300
na200
, co spowoduje zignorowanie wartości podanej w modyfikatorzesize
. - Wartość
Image
mieści się w tych granicach i ma rozmiar300
×200
, który jest przekazywany w górę drzewa.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
Ten fragment kodu generuje te dane wyjściowe:
- Modyfikator
fillMaxSize
dostosowuje ograniczenia, aby ustawić zarówno minimalną szerokość, jak i wysokość na wartość maksymalną –300dp
w przypadku szerokości i200dp
w przypadku wysokości. - Modyfikator
wrapContentSize
resetuje minimalne ograniczenia. Dlatego, gdyfillMaxSize
spowoduje ustalenie stałych ograniczeń,wrapContentSize
przywróci ograniczenia określone. Węzeł może teraz ponownie zajmować całą przestrzeń lub być mniejszy od niej. - Modyfikator
size
ustawia ograniczenia na minimalne i maksymalne granice50
. - Element
Image
ma rozmiar50
×50
, a modyfikatorsize
przekazuje ten rozmiar dalej. - Modyfikator
wrapContentSize
ma specjalną właściwość. Pobiera element podrzędny i umieszcza go na środku dostępnych minimalnych granic, które zostały mu przekazane. Rozmiar, który przekazuje do elementów nadrzędnych, jest więc równy minimalnym granicom, które zostały do niego przekazane.
Łącząc tylko 3 modyfikatory, możesz określić rozmiar funkcji kompozycyjnej i wyśrodkować ją w jej elemencie nadrzędnym.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
Ten fragment kodu generuje te dane wyjściowe:
- Modyfikator
clip
nie zmienia ograniczeń.- Modyfikator
padding
obniża maksymalne ograniczenia. - Modyfikator
size
ustawia wszystkie ograniczenia na100dp
. Image
spełnia te ograniczenia i podaje rozmiar100
×100dp
.- Modyfikator
padding
dodaje10dp
do wszystkich rozmiarów, więc zwiększa zgłaszaną szerokość i wysokość o20dp
. - W fazie rysowania modyfikator
clip
działa na obszarze o wymiarach120
×120dp
. Dlatego tworzy maskę w kształcie koła o tym rozmiarze. - Modyfikator
padding
wstawia wtedy treść o10dp
we wszystkich rozmiarach, więc zmniejsza rozmiar obszaru roboczego do100
×100dp
. - Na tym obszarze roboczym rysowany jest element
Image
. Obraz jest przycinany na podstawie pierwotnego okręgu120dp
, więc wynik nie jest okrągły.
- Modyfikator