Kolejność ograniczeń i modyfikatorów

W narzędziu Compose możesz połączyć wiele modyfikatorów, aby zmienić wygląd efektu kompozycyjnego. Te łańcuchy modyfikatorów mogą wpływać na ograniczenia przekazywane do komponentów, które definiują ograniczenia szerokości i wysokości.

Na tej stronie opisujemy, jak modyfikatory łańcuchowe wpływają na ograniczenia oraz i rozmieszczanie kompozycji.

Modyfikatory w drzewie interfejsu

Aby zrozumieć, jak modyfikatory wpływają na siebie nawzajem, warto zwizualizować pojawią się w drzewie interfejsu, które jest generowane na etapie tworzenia kompozycji. Dla: 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:

Kod elementów kompozycyjnych i modyfikatorów oraz ich wizualna reprezentacja w postaci drzewa interfejsu.
Rysunek 1. Modyfikatory opakowujące węzły układu w drzewie interfejsu.

Dodanie więcej niż jednego modyfikatora do kompozytowanego tworzy łańcuch modyfikatorów. Kiedy Jeśli połączysz wiele modyfikatorów, każdy węzeł modyfikatora opakuje resztę łańcucha i węzeł układu w obrębie. 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. W ten sposób modyfikator może zmienić rozmiar wymagań i umiejscowienia węzła modyfikatora lub układu, który jest opakowany.

Jak widać na rysunku 2, implementacja komponentów ImageText składa się z łańcucha modyfikatorów otaczających pojedynczy węzeł układu. Implementacje RowColumn to po prostu węzły układu, które opisują sposób rozmieszczania elementów podrzędnych.

Dotychczasową strukturę drzewa, ale teraz każdy węzeł ma po prostu prosty układ z wieloma modyfikatorami otaczającymi węzły.
Rysunek 2. Ta sama struktura drzewa jak na rysunku 1, ale z elementami kompozytowymi w drzewie interfejsu użytkownika zwizualizowanymi jako ciągi modyfikatorów.

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 kolejnych sekcjach opisujemy, jak za pomocą tego modelu mentalnego analizować łańcuch modyfikatorów i jak wpływa on na rozmiar komponentów.

Ograniczenia na etapie układu

Etap układu wykorzystuje 3-etapowy algorytm, aby znaleźć każdy układ. szerokość i wysokość węzła oraz współrzędne x i y:

  1. Mierz elementy podrzędne: węzeł mierzy swoje elementy podrzędne, jeśli takie istnieją.
  2. Decide own size (określ własny rozmiar): na podstawie tych pomiarów węzeł określa swój rozmiar.
  3. Umieść węzły podrzędne: każdy węzeł podrzędny jest umieszczany względem własnego węzła. pozycji.

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 mieć jedną z tych wartości:

  • Ograniczony: węzeł ma maksymalną i minimalną szerokość oraz wysokość.
.
Ograniczenia w ramach kontenera o różnych rozmiarach.
Rys. 3. Ograniczone ograniczenia.
  • Bez ograniczeń: węzeł nie jest ograniczony do żadnego rozmiaru. Maksymalne wartości szerokości i wysokości są ustawione na nieskończoność.
Nieograniczone ograniczenia, których szerokość i wysokość są ustawione na nieskończoność. Ograniczenia wykraczają poza kontener.
Rysunek 4. Nieograniczone ograniczenia.
  • Ścisły: węzeł ma spełniać wymagania dotyczące dokładnego rozmiaru. Minimalne i maksymalne wartości mają tę samą wartość.
Dokładne ograniczenia, które odpowiadają dokładnemu wymaganiu dotyczącemu rozmiaru w kontenerze.
Rysunek 5. Ograniczenia dokładne.
  • Kombinacja: węzeł korzysta z kombinacji powyższych 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ść.
Dwa kontenery, które pokazują kombinacje ograniczonych i nieograniczonych ograniczeń oraz dokładne wartości szerokości i wysokości.
Rysunek 6. Kombinacje ograniczonych i nieograniczonych ograniczeń oraz dokładnych szerokości i wzgórz.

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 układzie etap, ograniczenia są przekazywane z elementu nadrzędnego do elementu podrzędnego w drzewie UI.

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 decyduje o własnym rozmiarze, ale jest też zgodny z ograniczeniami przekazywanymi przez ma swoich rodziców.

Ogólnie algorytm działa w ten sposób:

  1. Aby określić rzeczywisty rozmiar, który ma zajmować, należy wybrać węzeł główny w drzewie interfejsu mierzy swoje elementy podrzędne i przekazuje te same ograniczenia do pierwszego elementu podrzędnego.
  2. Jeśli element podrzędny jest modyfikatorem, który nie ma wpływu na pomiary, przekazuje ograniczeń 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. rozmiary są następnie odpowiednio dostosowywane.
  3. Gdy dotrzeć do węzła, który nie ma żadnych elementów podrzędnych (nazywanych „liśćmi” węzeł”), określa on swój rozmiar na podstawie przekazanych ograniczeń, zwraca ten rozmiar do elementu nadrzędnego.
  4. Wydawca nadrzędny dostosowuje swoje ograniczenia na podstawie pomiarów dziecka. wywołuje kolejne dziecko z tymi skorygowanymi ograniczeniami.
  5. Gdy wszystkie elementy podrzędne zostaną zmierzone, węzeł nadrzędny określa swój rozmiar i przekazuje go swojemu rodzicowi.
  6. W ten sposób całe drzewo przechodzimy przede wszystkim na głębokości. Docelowo wszystkie węzły wybór rozmiarów i kończy się pomiar.

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:

Fragment drzewa UI z modyfikatorem rozmiaru obejmującym węzeł układu,
  reprezentuje ograniczone ograniczenia ustawione przez modyfikator rozmiaru w kontenerze.
Rysunek 7. Ograniczone ograniczenia w drzewie interfejsu i jego reprezentacja w kontenera.

Modyfikator size dostosowuje docierające ograniczenia do wartości, która została mu przekazana. W tym przykładzie wartość to 150dp:

Tak samo jak na ilustracji 7, z tą różnicą, że modyfikator rozmiaru dostosowuje przychodzące ograniczenia do przekazywanej do niej wartości.
Rysunek 8. Modyfikator size dostosowujący ograniczenia do wartości 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:

Dwa drzewa interfejsu użytkownika i ich reprezentacje w kontenerach. W pierwszym przypadku modyfikator rozmiaru akceptuje ograniczenia wejściowe, a w drugim dostosowuje się do ograniczeń zbyt dużych w jak największym stopniu, co powoduje, że ograniczenia wypełniają kontener.
Rysunek 9. Modyfikator size, który jak najdokładniej przestrzega przekazanego ograniczenia.

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:

łańcuch 2 modyfikatorów rozmiaru w drzewie UI i jego reprezentację w kontenerze;
  który jest wynikiem pierwszej przekazanej wartości, a nie drugiej.
Rysunek 10. Łańcuch 2 modyfikatorów size, w którym druga wartość przekazana (50dp) nie zastępuje pierwszej wartości (100dp).

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 funkcję ograniczeń przychodzących i przekazuje określony 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:

Modyfikator size i requiredSize połączone w drzewie interfejsu użytkownika oraz odpowiadająca im reprezentacja w kontenerze. Wymagane ograniczenia modyfikatora rozmiaru zastępują te z modyfikatorem rozmiaru
  .
Rysunek 11. Modyfikator requiredSize zastępuje ograniczenia przychodzące z modyfikatora size.

modyfikatory width i height,

Modyfikator size dostosowuje zarówno szerokość, jak i wysokość ograniczeń. Na modyfikatorem width, można ustawić stałą szerokość, ale wysokość nie zostanie określona. Podobnie za pomocą modyfikatora height możesz ustawić stałą wysokość, ale pozostawić szerokość nieokreśloną:

2 drzewa UI, jedno z modyfikatorem szerokości i reprezentacją kontenera,
  z modyfikatorem wysokości i jego reprezentacją.
Rysunek 12. Modyfikatory width i height ustawiają stałą szerokość i wysokość.

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.

Drzewo UI z modyfikatorem sizeIn z ustawioną minimalną i maksymalną szerokością i wysokością,
  i jego reprezentacji w kontenerze.
Rysunek 13. Modyfikator sizeIn z parametrami minWidth, maxWidth, minHeight i Ustawiono maxHeight.

Przykłady

W tej sekcji pokazano i objaśniono dane wyjściowe kilku fragmentów kodu, modyfikatory łańcuchowe.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .size(50.dp)
)

Ten fragment kodu generuje następujące dane wyjściowe:

  • Modyfikator fillMaxSize zmienia ograniczenia, aby ustawić zarówno minimalna szerokość i wysokość do wartości maksymalnej – 300dp szerokości i 200dp i wzrostu.
  • Choć modyfikator size chce używać rozmiaru 50dp, nadal potrzebuje aby zachować zgodność z przychodzącymi minimalnymi ograniczeniami. Dlatego modyfikator size będzie również zwracać dokładne granice ograniczenia 300 przez 200, ignorując przy tym wartość podawaną w modyfikatorze size.
  • Image postępuje zgodnie z tymi granicami i raportuje rozmiar 300 według parametru 200, który przebiega aż do samego końca drzewa.

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 i 200dp w przypadku wysokości.
  • Modyfikator wrapContentSize zeruje ograniczenia minimalne. Chociaż fillMaxSize spowodowało ograniczenie, wrapContentSize przywraca je do ograniczeń. Poniższy węzeł może teraz zajmować całą przestrzeń lub mniejsze od całego pokoju.
  • Modyfikator size ustawia ograniczenia na minimalne i maksymalne granice 50
  • Wartość Image jest przekształcana na rozmiar 50 przez 50, a modyfikator size przekazuje tę wartość.
  • Modyfikator wrapContentSize ma specjalną właściwość. Zabiera ona swoje dziecko i umieszcza je w środku dostępnych minimalnych granic, które zostały jej przekazane. Rozmiar, jaki przekazuje rodzicom, jest równy określonych minimalnych progów.

Łącząc tylko trzy modyfikatory, można zdefiniować rozmiar elementów wyśrodkowuje go na elemencie nadrzędnym.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .clip(CircleShape)
        .padding(10.dp)
        .size(100.dp)
)

Ten fragment kodu generuje następujące dane wyjściowe:

  • Modyfikator clip nie zmienia ograniczeń.
    • Modyfikator padding zmniejsza maksymalne ograniczenia.
    • Modyfikator size ustawia wszystkie ograniczenia na 100dp.
    • Image jest zgodny z tymi ograniczeniami i zgłasza rozmiar 100 przez 100dp
    • Modyfikator padding dodaje wartość 10dp do wszystkich rozmiarów, więc zwiększa on raportowanie szerokość i wysokość o 20dp.
    • Na etapie rysowania modyfikator clip działa na obszarze roboczym 120 przez 120dp Tworzy on więc maskę koła o tym rozmiarze.
    • Modyfikator padding wstawia następnie zawartość o wartość 10dp we wszystkich rozmiarach, przez co zmniejsza rozmiar płótna do 100 o wartość 100dp.
    • Na tym obszarze roboczym jest narysowany element Image. Obraz jest przycinany na podstawie pierwotny okrąg 120dp, więc wynikiem nie jest okrąg.