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 komponentów, które definiują granice szerokości i wysokości.
Na tej stronie wyjaśniamy, jak zmodyfikowane modyfikatory wpływają na ograniczenia, a w konsekwencji na pomiar i umiejscowienie komponentów.
Modyfikatory w drzewie interfejsu
Aby zrozumieć, jak modyfikatory wpływają na siebie nawzajem, warto zwizualizować, jak są one wyświetlane w drzewie interfejsu użytkownika, które jest generowane w trakcie fazy tworzenia. Więcej informacji znajdziesz w sekcji Kompozycja.
W drzewie interfejsu użytkownika modyfikatory możesz wizualizować jako węzły opakowania dla węzłów układu:
Dodanie więcej niż jednego modyfikatora do kompozytowanego tworzy łańcuch 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 na przykład połączysz modyfikator clip
z modyfikatorem size
, węzeł modyfikatora clip
otacza węzeł modyfikatora size
, który z kolei otacza węzeł układu Image
.
W fazie układu algorytm przechodzący po drzewie pozostaje taki sam, ale odwiedza też każdy węzeł modyfikatora. Dzięki temu modyfikator może zmienić wymagania dotyczące rozmiaru i umieszczenie modyfikatora lub węzła układu, który otacza.
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 Row
i Column
to po prostu węzły układu, które opisują sposób rozmieszczania elementów podrzędnych.
Podsumowując:
- Modyfikatory otaczają pojedynczy modyfikator lub węzeł układu.
- Węzły układu mogą zawierać wiele węzłów podrzędnych.
W kolejnych sekcjach opisujemy, jak za pomocą tego modelu mentalnego analizować łańcuch modyfikatorów i jak wpływa on na rozmiar komponentów.
Ograniczenia w etapu układu
Etap układu polega na znalezieniu szerokości, wysokości i współrzędnych x, y każdego węzła układu za pomocą algorytmu o 3 etapach:
- Pomiar podrzędnych: węzeł mierzy swoje podrzędne, jeśli takie istnieją.
- Ustal własny rozmiar: na podstawie tych pomiarów węzeł decyduje o własnym rozmiarze.
- Umieszczanie podrzędnych węzłów: każdy podrzędny węzeł jest umieszczany względem pozycji węzła.
Constraints
pomagają znaleźć odpowiednie rozmiary węzłów w pierwszych 2 krokach algorytmu. Ograniczenia określają minimalne i maksymalne wartości szerokości i wysokości węzła. Gdy węzeł określa swój rozmiar, zmierzony rozmiar powinien mieścić się w tym zakresie.
Typy ograniczeń
Ograniczenie może być jednym z tych elementów:
- Ograniczony: węzeł ma maksymalną i minimalną szerokość i wysokość.
- Bez ograniczeń: węzeł nie jest ograniczony żadnym rozmiarem. Maksymalne wartości szerokości i wysokości są ustawione na nieskończoność.
- Dokładne: węzeł musi spełniać dokładne wymagania dotyczące rozmiaru. Minimalne i maksymalne wartości mają tę samą wartość.
- Kombinacja: węzeł stosuje kombinację wymienionych powyżej 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 podrzędnego.
Jak ograniczenia są przekazywane z elementu nadrzędnego do podrzędnego
W pierwszym kroku algorytmu opisanym w sekcji Ograniczenia w etapie układu ograniczenia są przekazywane z elementu nadrzędnego do podrzędnego w drzewie interfejsu.
Gdy węzeł nadrzędny mierzy swoje węzły podrzędne, przekazuje te ograniczenia do każdego węzła podrzędnego, aby wiedział, jak duży lub mały może być. Następnie, gdy określa swój rozmiar, musi też przestrzegać ograniczeń przekazanych przez swoich rodziców.
Ogólnie algorytm działa w ten sposób:
- Aby określić rozmiar, który chce zająć, węzeł główny w drzewie interfejsu użytkownika 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 wpływa na pomiar, przekazuje ograniczenia do następnego modyfikatora. Ograniczenia są przekazywane w łańcuchu modyfikatorów bez zmian, chyba że zostanie osiągnięty modyfikator, który wpływa na pomiar. a następnie dostosowuje się do nich ograniczenia.
- Gdy zostanie osiągnięty węzeł, który nie ma żadnych węzłów podrzędnych (nazywany „węzłem końcowym”), określa on swój rozmiar na podstawie podanych ograniczeń i zwraca ten rozmiar do węzła nadrzędnego.
- Jednostka nadrzędna dostosowuje swoje ograniczenia na podstawie pomiarów elementu podrzędnego i wywołuje kolejne z wykorzystaniem tych dostosowanych ograniczeń.
- Gdy wszystkie elementy podrzędne zostaną zmierzone, węzeł nadrzędny określa swój rozmiar i przekazuje go swojemu rodzicowi.
- W ten sposób całe drzewo przechodzimy przede wszystkim na głębokości. Ostatecznie wszystkie węzły określają swoje rozmiary i kończy się etap pomiaru.
Szczegółowy przykład znajdziesz w filmie Ograniczenia i kolejność modyfikatorów.
Modyfikatory wpływające na ograniczenia
Z poprzedniej sekcji wiesz już, że niektóre modyfikatory mogą wpływać na rozmiar ograniczeń. W sekcjach poniżej opisujemy konkretne modyfikatory, które wpływają na ograniczenia.
modyfikator size
Modyfikator size
określa preferowany rozmiar treści.
Na przykład to drzewo interfejsu powinno być renderowane w kontenerze 300dp
200dp
. Ograniczenia są ograniczone, co pozwala na szerokość w zakresie od 100dp
do
300dp
oraz wysokość w zakresie od 100dp
do 200dp
:
Modyfikator size
dostosowuje docierające ograniczenia do wartości, która została mu przekazana.
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 zażąda mniejszego lub większego rozmiaru, musi on nadal mieścić się w dokładnych granicach, więc nie zastąpi tych wartości:
modyfikator requiredSize
Jeśli chcesz, aby twój węzeł zastąpił docierające ograniczenia, użyj modyfikatora requiredSize
zamiast size
. Modyfikator requiredSize
zastępuje docierające ograniczenia i przekazuje podany przez Ciebie rozmiar jako dokładne granice.
Gdy rozmiar zostanie przekazany 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 pozostawić nieokreśloną wysokość.
I podobnie, za pomocą modyfikatora height
możesz ustawić stałą wysokość, ale szerokość pozostaw nieokreśloną:
modyfikator sizeIn
Modyfikator sizeIn
umożliwia ustawienie dokładnych ograniczeń minimalnych i maksymalnych dla szerokości i wysokości. Jeśli potrzebujesz szczegółowej kontroli nad ograniczeniami, użyj modyfikatora sizeIn
.
Przykłady
Ta sekcja pokazuje i wyjaśnia dane wyjściowe z kilku fragmentów kodu z łańcuchowymi modyfikatorami.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
Ten fragment kodu zwraca te dane wyjściowe:
- Modyfikator
fillMaxSize
zmienia ograniczenia, aby ustawić minimalną szerokość i wysokość na maksymalną wartość –300dp
w szerokości i200dp
– w wysokości. - Mimo że modyfikator
size
chce użyć rozmiaru50dp
, musi on nadal przestrzegać minimalnych ograniczeń wejściowych. Dlatego modyfikatorsize
będzie też zwracać dokładne granice ograniczenia300
przez200
, ignorując przy tym wartość podawaną w modyfikatorzesize
. - Element
Image
podąża za tymi granicami i podaje rozmiar300
według200
, który jest przekazywany w górę po drzewie.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
Ten fragment kodu generuje 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
zeruje ograniczenia minimalne. ChociażfillMaxSize
spowodowało ograniczenie,wrapContentSize
przywraca je do ograniczeń. Następny węzeł może znowu zajmować całą przestrzeń lub być mniejszy niż cała przestrzeń. - Modyfikator
size
ustawia minimalne i maksymalne wartości parametru50
. Image
przyjmuje rozmiar50
o50
i modyfikatorsize
to odpowiednio.- Modyfikator
wrapContentSize
ma specjalną właściwość. Zabiera ono swoje dziecko i umieszcza je w ś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 minimalnemu progowi, który został do niego przesłany.
Łącząc tylko 3 modyfikatory, możesz zdefiniować rozmiar kompozytu i wyśrodkować go w rodzicu.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
Ten fragment kodu powoduje wyświetlenie tych danych wyjściowych:
- Modyfikator
clip
nie zmienia ograniczeń.- Modyfikator
padding
obniża maksymalne ograniczenia. - Modyfikator
size
ustawia wszystkie ograniczenia na100dp
. - Funkcja
Image
przestrzega tych ograniczeń i podaje rozmiar100
w ramach100dp
. - Modyfikator
padding
dodaje10dp
do wszystkich rozmiarów, co zwiększa zgłaszaną szerokość i wysokość o20dp
. - W fazie rysowania modyfikator
clip
działa na płótnie o wymiarach120
przez120dp
. W tym celu tworzy maskę koła o takim rozmiarze. - Modyfikator
padding
wstawia zawartość obiektu o10dp
we wszystkich rozmiarach, więc zmniejsza rozmiar obszaru roboczego do100
o100dp
. - W tym obszarze roboczym narysowany jest element
Image
. Obraz jest przycięty na podstawie oryginalnego koła o promieniu120dp
, więc wynik nie jest okrągły.
- Modyfikator