W narzędziu Compose możesz połączyć wiele modyfikatorów, aby zmienić wygląd i sposób działania funkcji kompozycyjnej. 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 modyfikatory łańcuchowe wpływają na ograniczenia, a także na pomiary i rozmieszczenie elementów kompozycyjnych.
Modyfikatory w drzewie interfejsu
Aby zrozumieć, jak modyfikatory wpływają na siebie nawzajem, warto zwizualizować ich wygląd w drzewie interfejsu generowanym na etapie tworzenia kompozycji. Więcej informacji znajdziesz w sekcji Kompozycja.
W drzewie interfejsu możesz zwizualizować modyfikatory jako węzły otoki węzłów układu:
Dodanie więcej niż 1 modyfikatora do funkcji kompozycyjnej powoduje utworzenie łańcucha modyfikatorów. W przypadku połączenia wielu modyfikatorów każdy węzeł modyfikujący opakowuje resztę łańcucha i węzeł układu w obrębie łańcucha. Jeśli np. łączysz łańcuch clip
i modyfikatora size
, węzeł modyfikatora clip
opakowuje węzeł modyfikatora size
, który następnie opakowuje węzeł układu Image
.
Na etapie układu algorytm, który spaceruje po drzewie, pozostaje taki sam, ale odwiedzany jest też każdy węzeł modyfikujący. W ten sposób modyfikator może zmienić wymagania dotyczące rozmiaru i położenie węzła modyfikatora lub układu, który jest opakowany.
Jak widać na rys. 2, samo wdrożenie elementów kompozycyjnych Image
i Text
składa się z łańcucha modyfikatorów opakowujących pojedynczy węzeł układu. Implementacje obiektów Row
i Column
to po prostu węzły układu, które opisują, jak rozmieszczać elementy podrzędne.
Podsumowując:
- Modyfikatory obejmują pojedynczy węzeł modyfikatora lub układu.
- Węzły układu mogą rozmieszczać wiele węzłów podrzędnych.
W kolejnych sekcjach opisujemy, jak korzystać z tego modelu psychicznego do analizowania łańcuchów modyfikatorów i jak wpływa on na rozmiar elementów kompozycyjnych.
Ograniczenia na etapie układu
Faza układu używa trzyetapowego algorytmu, który wyszukuje szerokość i wysokość każdego węzła układu oraz współrzędne x i y:
- Mierz elementy podrzędne: węzeł mierzy swoje elementy podrzędne, jeśli takie istnieją.
- Ustal własny rozmiar: na podstawie tych pomiarów węzeł decyduje o własnym rozmiarze.
- Umieść węzeł podrzędny: każdy węzeł podrzędny jest umieszczany względem jego własnej pozycji.
Constraints
pomaga znaleźć odpowiednie rozmiary dla 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ł decyduje o swoim rozmiarze, zmierzony rozmiar powinien mieścić się w tym zakresie rozmiarów.
Typy ograniczeń
Ograniczenie może mieć jedną z tych wartości:
- Ograniczony: węzeł ma maksymalną i minimalną szerokość i wysokość.
- Bez ograniczeń: węzeł nie jest ograniczony do żadnego rozmiaru. Granice maksymalnej szerokości i wysokości są ustawione na nieskończoność.
- Ścisły: węzeł ma spełniać wymagania dotyczące dokładnego rozmiaru. Minimalne i maksymalne granice mają taką samą wartość.
- Kombinacja: węzeł korzysta z kombinacji powyższych typów ograniczeń. Ograniczenie może na przykład ograniczyć szerokość, zezwalając na nieograniczoną maksymalną wysokość, lub ustawić dokładną szerokość, a jednocześnie 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 zasady nadrzędnej do podrzędnej
W pierwszym kroku algorytmu opisanym w sekcji Ograniczenia w fazie 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, podaje te ograniczenia każdemu podrzędnemu elementowi, aby poinformować je, jak duże lub małe mogą być te obiekty. Gdy decyduje o własnym rozmiarze, przestrzega też ograniczeń ustalonych przez jego rodziców.
Ogólnie algorytm działa w ten sposób:
- Aby określić rzeczywisty rozmiar, który ma zajmować, węzeł główny w drzewie interfejsu 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 pomiary, przekierowuje ograniczenia do następnego modyfikatora. Ograniczenia są przekazywane do łańcucha modyfikatorów w niezmienionej postaci, chyba że zostanie osiągnięty modyfikator wpływający na pomiar. a następnie dostosowuje się do nich ograniczenia.
- Gdy dotrzesz do węzła, który nie ma żadnych elementów podrzędnych (nazywanych „węzłem liścia”), określa swój rozmiar na podstawie przekazanych ograniczeń i zwraca ten zakończony rozmiar do elementu nadrzędnego.
- Jednostka nadrzędna dostosowuje swoje ograniczenia na podstawie pomiarów elementu podrzędnego i wywołuje kolejny element podrzędny z tymi dostosowanymi ograniczeniami.
- Po zmierzeniu wszystkich elementów podrzędnych węzła nadrzędnego ustala on swój rozmiar i przekazuje go do swojego elementu nadrzędnego.
- W ten sposób całe drzewo przechodzimy przede wszystkim na głębokości. W końcu wszystkie węzły mają już wybrane rozmiary i etap pomiaru jest zakończony.
Szczegółowy przykład znajdziesz w filmie Ograniczenia i kolejność modyfikatorów.
Modyfikatory wpływające na ograniczenia
W poprzedniej sekcji wiesz, ż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 poniższe drzewo interfejsu powinno zostać wyrenderowane w kontenerze 300dp
przez 200dp
. Ograniczenia są ograniczone, co pozwala na szerokość od 100dp
do 300dp
oraz wysokość od 100dp
do 200dp
:
Modyfikator size
dostosowuje przychodzące ograniczenia tak, aby pasowały do przekazywanej do niej wartości.
W tym przykładzie wartość to 150dp
:
Jeśli szerokość i wysokość są mniejsze niż najmniejsza granica ograniczenia lub większe od największego, modyfikator jak najdokładniej dopasowuje przekazywane ograniczenia, jednocześnie przestrzegając podanych ograniczeń:
Pamiętaj, że łączenie 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 wymaga mniejszej lub większego rozmiaru, musi przestrzegać podanych granic, więc nie zastępuje tych wartości:
Modyfikator requiredSize
Jeśli chcesz zastąpić przychodzące ograniczenia, użyj modyfikatora requiredSize
zamiast size
. Modyfikator requiredSize
zastępuje przychodzące ograniczenia i przekazuje określony rozmiar jako dokładne granice.
Po przekazaniu rozmiaru z powrotem do drzewa, węzeł podrzędny zostanie wyśrodkowany w dostępnej przestrzeni:
Modyfikatory width
i height
Modyfikator size
dostosowuje zarówno szerokość, jak i wysokość ograniczeń. Za pomocą modyfikatora width
możesz ustawić stałą szerokość, ale wysokość nie zostanie określona.
I podobnie, za pomocą modyfikatora height
możesz ustawić stałą wysokość, ale szerokość pozostaw nieokreśloną:
Modyfikator sizeIn
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
Ta sekcja przedstawia i objaśnia dane wyjściowe kilku fragmentów kodu z łańcuchami modyfikatorów.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
Ten fragment kodu daje następujące dane wyjściowe:
- Modyfikator
fillMaxSize
zmienia ograniczenia tak, aby ustawić minimalną szerokość i wysokość na wartość maksymalną –300dp
i200dp
wysokości. - Mimo że modyfikator
size
ma używać rozmiaru50dp
, musi przestrzegać przychodzących ograniczeń minimalnych. Dlatego modyfikatorsize
zwróci też dokładne granice ograniczenia300
o200
, co spowoduje zignorowanie wartości podanej w modyfikatorzesize
. Image
przekracza te granice i raportuje rozmiar300
o wartości200
, która jest przekazywana aż do wysokości drzewa.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
Ten fragment kodu daje następujące dane wyjściowe:
- Modyfikator
fillMaxSize
dostosowuje ograniczenia tak, aby ustawić minimalną szerokość i wysokość do wartości maksymalnej –300dp
szerokości i200dp
w wysokości. - Modyfikator
wrapContentSize
resetuje minimalne ograniczenia. Mimo że funkcjafillMaxSize
spowodowała stałe ograniczenia,wrapContentSize
przywraca ją z powrotem do ograniczeń ograniczonych. Poniższy węzeł może ponownie zająć całą przestrzeń lub być od niej mniejszy. - Modyfikator
size
ustawia ograniczenia na minimalny i maksymalny próg50
. Image
przyjmuje rozmiar50
o50
i modyfikatorsize
to odpowiednio.- Modyfikator
wrapContentSize
ma specjalną właściwość. Zabiera element podrzędny i umieszcza go w środku dostępnych minimalnych granic, które zostały do niego przekazane. Rozmiar, który przekazuje do elementów nadrzędnych, jest więc równy minimalnemu progowi, który został do niego przesłany.
Łącząc tylko 3 modyfikatory, możesz zdefiniować rozmiar funkcji kompozycyjnej i wyśrodkować ją w elemencie nadrzędnym.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
Ten fragment kodu daje następujące dane wyjściowe:
- Modyfikator
clip
nie zmienia ograniczeń.- Modyfikator
padding
obniża maksymalne ograniczenia. - Modyfikator
size
ustawia wszystkie ograniczenia na100dp
. Image
jest zgodny z tymi ograniczeniami i raportuje rozmiar100
na100dp
.- Modyfikator
padding
dodaje wartość10dp
we wszystkich rozmiarach, więc zwiększa szerokość i wysokość o20dp
. - Na etapie rysowania modyfikator
clip
działa na obszarze roboczym120
przez120dp
. Tworzy on więc maskę koła o tym rozmiarze. - Modyfikator
padding
wstawia treść za pomocą właściwości10dp
we wszystkich rozmiarach, więc zmniejsza rozmiar obszaru roboczego do100
o100dp
. - W tym obszarze roboczym narysowany jest element
Image
. Obraz zostanie przycięty na podstawie pierwotnego okręgu120dp
, więc wynik nie będzie okrągły.
- Modyfikator