W interfejsie tworzenia możesz łączyć wiele modyfikatorów, aby zmienić wygląd i styl funkcji kompozycyjnej. Te łańcuchy modyfikatorów mogą wpływać na ograniczenia przekazywane do funkcji kompozycyjnych, które definiują granice szerokości i wysokości.
Na tej stronie opisujemy, jak łańcuchowe modyfikatory wpływają na ograniczenia, a co za tym idzie na pomiar i rozmieszczanie elementów kompozycyjnych.
Modyfikatory w drzewie interfejsu
Aby zrozumieć, jak modyfikatory wpływają na siebie nawzajem, warto zwizualizować ich wygląd w drzewie interfejsu, które jest generowane na etapie kompozycji. Więcej informacji znajdziesz w sekcji Kompozycja.
W drzewie interfejsu możesz wizualizować modyfikatory jako węzły układu dla węzłów układu:
Dodanie więcej niż jednego modyfikatora do funkcji kompozycyjnej powoduje utworzenie łańcucha modyfikatorów. Gdy połączysz wiele modyfikatorów, każdy z nich otacza pozostałe elementy łańcucha i węzeł układu. Gdy na przykład dołączasz łańcuch clip
i modyfikator size
, węzeł modyfikatora clip
opakowuje węzeł z modyfikatorem size
, który następnie opakowuje węzeł układu Image
.
Na etapie układu algorytm poruszający się po drzewie pozostaje taki sam, ale odwiedzany jest też każdy węzeł modyfikatora. W ten sposób modyfikator może zmienić wymagania dotyczące rozmiaru oraz jego umiejscowienie dla modyfikatora lub węzła układu, który uwzględnia.
Jak widać na Rysunku 2, implementacja elementów kompozycyjnych Image
i Text
składa się z łańcucha modyfikatorów obejmujących 1 węzeł układu. Implementacje Row
i Column
są po prostu węzłami układu, które opisują sposób rozmieszczenia elementów podrzędnych.
Podsumujmy:
- Modyfikatory zawijają pojedynczy modyfikator lub węzeł układu.
- Węzły układu mogą obejmować wiele węzłów podrzędnych.
W kolejnych sekcjach opisujemy, jak z tego modelu myślowego myśleć o łańcuchu modyfikatorów i jak wpływa on na rozmiar elementów kompozycyjnych.
Ograniczenia na etapie układu
Etap układu korzysta z 3-etapowego algorytmu, który znajduje szerokość i wysokość węzła układu oraz współrzędne x i y:
- Pomiar elementów podrzędnych: węzeł mierzy elementy podrzędne (jeśli występują).
- Ustal własny rozmiar: na podstawie tych pomiarów węzeł określa własny rozmiar.
- Umieść elementy podrzędne: każdy węzeł podrzędny jest umieszczany względem własnego węzła.
Constraints
pomaga znaleźć odpowiednie rozmiary węzłów podczas pierwszych 2 etapów algorytmu. Ograniczenia określają minimalne i maksymalne granice szerokości i wysokości węzła. Gdy węzeł określi swój rozmiar, jego zmierzony rozmiar powinien mieścić się w tym zakresie.
Typy ograniczeń
Możliwe ograniczenia:
- Ograniczony: węzeł ma maksymalną i minimalną szerokość oraz wysokość.
- Bez ograniczeń: węzeł nie jest ograniczony do żadnego rozmiaru. Maksymalne progi szerokości i wysokości są ustawione na nieskończoność.
- Ścisłe: węzeł jest pytany o wymagania dotyczące dokładnego rozmiaru. Progi minimalne i maksymalne są ustawione na tę samą wartość.
- Kombinacja: węzeł korzysta z kombinacji powyższych typów ograniczeń. Na przykład ograniczenie może ograniczyć szerokość, zezwalając na nieskończoną maksymalną wysokość, lub określić dokładną szerokość, ale jednocześnie określić wysokość.
W następnej sekcji opisano sposób przekazywania tych ograniczeń z elementu nadrzędnego do jednostki podrzędnej.
W jaki sposób ograniczenia są przekazywane z jednostki nadrzędnej do podrzędnej
W pierwszym kroku algorytmu opisanego na stronie Ograniczenia na etapie układu ograniczenia są przekazywane z elementu nadrzędnego do elementu podrzędnego w drzewie interfejsu.
Gdy węzeł nadrzędny mierzy swoje elementy podrzędne, ogranicza te ograniczenia każdemu z podrzędnych, aby poinformować, jak duży lub mały węzeł może być dozwolony. Następnie, gdy sam określi swój rozmiar, przestrzega również ograniczeń określonych przez rodziców.
Ogólnie algorytm działa w ten sposób:
- Aby określić rozmiar, jaki będzie on miał zająć, węzeł główny w drzewie interfejsu mierzy elementy podrzędne i przekazuje te same ograniczenia do swojego pierwszego węzła podrzędnego.
- Jeśli element podrzędny jest modyfikatorem, który nie ma wpływu na pomiar, przekierowuje te 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 wpływa na pomiar. Rozmiar ograniczeń jest następnie odpowiednio zmieniany.
- Po dotarciu do węzła niemającego żadnych elementów podrzędnych (nazywanych „węzłem liścia”) określa on jego rozmiar na podstawie przekazanych ograniczeń i zwraca ten rozwiązany rozmiar do elementu nadrzędnego.
- Element nadrzędny dostosowuje swoje ograniczenia na podstawie pomiarów tego elementu podrzędnego i wywołuje jego kolejne elementy podrzędne z tymi dostosowanymi ograniczeniami.
- Po zmierzeniu wszystkich elementów podrzędnych węzła nadrzędnego określa on swój rozmiar i przekazuje go do własnego węzła nadrzędnego.
- W ten sposób przemierzane są najpierw całe drzewo. Ostatecznie wszystkie węzły określiły swoje rozmiary i zakończony jest pomiar.
Szczegółowy przykład znajdziesz w filmie Ograniczenia i kolejność modyfikatorów.
Modyfikatory, które mają wpływ na ograniczenia
W poprzedniej sekcji omówiliśmy, że niektóre modyfikatory mogą wpływać na rozmiar ograniczenia. W sekcjach poniżej opisujemy konkretne modyfikatory, które mają wpływ na ograniczenia.
size
modyfikator
Modyfikator size
deklaruje preferowany rozmiar treści.
Na przykład to drzewo interfejsu powinno być renderowane w kontenerze 300dp
na 200dp
. Ograniczenia są ograniczone, co umożliwia szerokości od 100dp
do 300dp
oraz wysokości od 100dp
do 200dp
:
Modyfikator size
dostosowuje ograniczenia przychodzące do przekazywanej wartości.
W tym przykładzie wartość to 150dp
:
Jeśli szerokość i wysokość są mniejsze niż najmniejsze lub większe niż największa granica ograniczenia, modyfikator jak najwierniej odpowiada przekazywanemu ograniczeniom i jednocześnie zachowuje zgodność z przekazanymi ograniczeniami:
Pamiętaj, że łączenie w łańcuch wielu 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 żąda mniejszego lub większego rozmiaru, musi przestrzegać dokładnych granic przekazanych, więc nie zastępuje tych wartości:
requiredSize
modyfikator
Jeśli chcesz, aby węzeł zastąpił przychodzące ograniczenia, zamiast size
użyj modyfikatora requiredSize
. Modyfikator requiredSize
zastępuje przychodzące ograniczenia i przekazuje podany przez Ciebie rozmiar jako dokładne wartości progowe.
Po przesłaniu rozmiaru z powrotem do drzewa węzeł podrzędny zostanie wyśrodkowany w dostępnym miejscu:
Modyfikatory width
i height
Modyfikator size
dostosowuje szerokość i wysokość ograniczeń. Korzystając z modyfikatora width
, możesz ustawić stałą szerokość, ale wysokość pozostawić niezdecydowaną.
Podobnie dzięki modyfikatorowi height
możesz ustawić stałą wysokość, ale pozostawić szerokość nieokreśloną:
sizeIn
modyfikator
Modyfikator sizeIn
pozwala ustawić dokładne minimalne i maksymalne ograniczenia szerokości i wysokości. Jeśli potrzebujesz szczegółowej kontroli nad ograniczeniami, użyj modyfikatora sizeIn
.
Przykłady
W tej sekcji widać i objaśniamy dane wyjściowe z kilku fragmentów kodu z łańcuchami modyfikatorów.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
Ten fragment kodu wygeneruje następujące dane wyjściowe:
- Modyfikator
fillMaxSize
zmienia ograniczenia, ustawiając zarówno minimalną szerokość, jak i wysokość na wartość maksymalną, czyli300dp
szerokości i200dp
wysokości. - Mimo że modyfikator
size
chce użyć rozmiaru50dp
, i tak musi spełniać przychodzące minimalne ograniczenia. Dlatego modyfikatorsize
zwraca też dokładne wartości progowe ograniczenia300
przez200
, co w efekcie ignoruje wartość podaną w modyfikatorzesize
. - Obiekt
Image
przekracza te granice i raportuje rozmiar300
dla200
, który jest przekazywany aż do samego dołu drzewa.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
Ten fragment kodu wygeneruje następujące dane wyjściowe:
- Modyfikator
fillMaxSize
dostosowuje ograniczenia tak, aby ustawić minimalną szerokość i wysokość do wartości maksymalnej – szerokości300dp
i200dp
wysokości. - Modyfikator
wrapContentSize
resetuje minimalne ograniczenia. Choć funkcjafillMaxSize
spowodowała stałe ograniczenia,wrapContentSize
resetuje ją do ograniczonych ograniczeń. Poniższy węzeł może teraz ponownie zająć całą przestrzeń lub być mniejszy. - Modyfikator
size
wyznacza ograniczenia na minimalną i maksymalną wartość50
. - Element
Image
przyjmuje wartość50
według50
, a modyfikatorsize
przekazuje tę informację do przodu. - Modyfikator
wrapContentSize
ma specjalną właściwość. Wykorzystuje element podrzędny i umieszcza w środku dostępnych minimalnych wartości progowych, które zostały do niego przesłane. Rozmiar, jaki przekazuje z elementami nadrzędnymi, jest więc równy minimalnych progach, które do niej zostały przekazane.
Łącząc tylko 3 modyfikatory, możesz zdefiniować rozmiar elementu kompozycyjnego i wyśrodkować go w jego elemencie nadrzędnym.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
Ten fragment kodu wygeneruje następujące dane wyjściowe:
- Modyfikator
clip
nie zmienia ograniczeń.- Modyfikator
padding
obniża maksymalne ograniczenia. - Modyfikator
size
ustawia wszystkie ograniczenia na100dp
. - Element
Image
jest zgodny z tymi ograniczeniami i zgłasza rozmiar100
według100dp
. - Modyfikator
padding
dodaje element10dp
we wszystkich rozmiarach, więc zwiększa raportowane dane szerokości i wysokości o20dp
. - Na etapie rysowania modyfikator
clip
działa na obszarze roboczym elementu120
przez120dp
. Utworzy wtedy maskę kołową o tym rozmiarze. - Następnie modyfikator
padding
wstawia swoją zawartość o10dp
we wszystkich rozmiarach, więc zmniejsza rozmiar obszaru roboczego do100
o100dp
. - Element
Image
jest narysowany na tym obszarze roboczym. Obraz jest przycinany na podstawie pierwotnego okręgu ustawionego na120dp
, więc wynik nie jest okrągły.
- Modyfikator