W sekcji „Tworzenie” możesz łączyć ze sobą wiele modyfikatorów, aby zmieniać wygląd i wygląd komponentu. 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 użytkownika
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. Gdy połączysz ze sobą wiele modyfikatorów, każdy z nich obejmuje pozostałą część łańcucha oraz węzeł układu. Jeśli na przykład połączysz modyfikator clip
z modyfikatorem size
, węzeł modyfikatora clip
spowoduje oznaczenie węzła modyfikatora size
, który z kolei spowoduje oznaczenie węzła 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 rysunku 2, implementacja komponentów Image
i Text
składa się z łańcucha modyfikatorów otaczają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ńcuchy modyfikatorów i jak wpływają one na rozmiar elementów składanych.
Ograniczenia na etapie 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 składającego się z 3 etapów:
- Pomiar podrzędnych: węzeł mierzy swoje podrzędne, jeśli takie istnieją.
- Decide own size (określ własny rozmiar): na podstawie tych pomiarów węzeł określa swój rozmiar.
- 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ść oraz 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ń. Na przykład ograniczenie może określać szerokość, ale nie ograniczać maksymalnej wysokości, lub określać dokładną szerokość, ale nie 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 nadrzędnych.
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. Następnie odpowiednio zmieniane są rozmiary ograniczeń.
- 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.
- Element nadrzędny dostosowuje swoje ograniczenia na podstawie pomiarów podrzędnego i wywołuje następny element podrzędny z tymi dostosowanymi ograniczeniami.
- 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 jest przeszukiwane metodą głębokresową. Ostatecznie wszystkie węzły określają swoje rozmiary i kończy się etap pomiaru.
Szczegółowy przykład znajdziesz w filmie Zasady 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 następnych sekcjach 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 od najmniejszego ograniczenia lub większe od największego ograniczenia, modyfikator dopasowuje się do podanych ograniczeń w jak największym stopniu, zachowując jednocześnie ograniczenia podane w ramach:
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ść.
Podobnie za pomocą modyfikatora height
możesz ustawić stałą wysokość, ale pozostawić szerokość nieokreśloną:
modyfikator sizeIn
,
Modyfikator sizeIn
umożliwia ustawienie dokładnych ograniczeń minimalnych i maksymalnych dla szerokości i wysokości. Jeśli chcesz mieć szczegółową kontrolę 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 powoduje wyświetlenie tych danych wyjściowych:
- 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 powoduje wyświetlenie tych danych wyjściowych:
- Modyfikator
fillMaxSize
dostosowuje ograniczenia, aby ustawić minimalną szerokość i wysokość do maksymalnej wartości –300dp
w przypadku szerokości i200dp
w przypadku 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
. - Wartość
Image
jest przekształcana na rozmiar50
przez50
, a modyfikatorsize
przekazuje tę wartość dalej. - 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 jest przekazywany do elementów nadrzędnych, jest więc równy minimalnym granicom, które zostały mu przekazane.
Łą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
zmniejsza 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 następnie zawartość o wartość10dp
we wszystkich rozmiarach, przez co zmniejsza rozmiar płótna do100
o wartość100dp
. - Na tym obszarze roboczym jest narysowany element
Image
. Obraz jest przycięty na podstawie oryginalnego koła o promieniu120dp
, więc wynik nie jest okrągły.
- Modyfikator