Podsumowanie rozdziału 26. Układy niestandardowe
Uwaga
Ta książka została opublikowana wiosną 2016 roku i od tego czasu nie została zaktualizowana. Jest wiele w książce, która pozostaje cenna, ale niektóre materiały są nieaktualne, a niektóre tematy nie są już całkowicie poprawne ani kompletne.
Xamarin.Forms zawiera kilka klas pochodnych z Layout<View>
klasy :
StackLayout
,Grid
,AbsoluteLayout
iRelativeLayout
.
W tym rozdziale opisano sposób tworzenia własnych klas, które pochodzą z klasy Layout<View>
.
Omówienie układu
Nie ma scentralizowanego systemu obsługującego Xamarin.Forms układ. Każdy element jest odpowiedzialny za określenie własnego rozmiaru oraz sposób renderowania się w określonym obszarze.
Rodzice i dzieci
Każdy element, który ma dzieci, jest odpowiedzialny za pozycjonowanie tych dzieci w sobie. Jest to element nadrzędny, który ostatecznie określa, jaki rozmiar powinien mieć jego elementy podrzędne na podstawie dostępnego rozmiaru i rozmiaru, jaki chce mieć dziecko.
Ustalanie rozmiaru i pozycjonowanie
Układ rozpoczyna się w górnej części drzewa wizualnego ze stroną, a następnie przechodzi przez wszystkie gałęzie. Najważniejszą metodą publiczną w układzie jest Layout
zdefiniowana przez VisualElement
element . Każdy element, który jest elementem nadrzędnym do innych elementów, wymaga Layout
, aby każde z jego elementów podrzędnych dało dziecku rozmiar i pozycję względem siebie w postaci Rectangle
wartości. Te Layout
wywołania są propagowane za pomocą drzewa wizualnego.
Wywołanie elementu jest wymagane, aby Layout
element był wyświetlany na ekranie i powoduje ustawienie następujących właściwości tylko do odczytu. Są one zgodne z przekazanym Rectangle
do metody :
Przed wywołaniem Layout
Height
i Width
mają wyśmiewane wartości –1.
Wywołanie wyzwala Layout
również wywołania następujących metod chronionych:
SizeAllocated
, który wywołujeOnSizeAllocated
, które można przesłonić.
Na koniec zostanie wyzwolone następujące zdarzenie:
Metoda OnSizeAllocated
jest zastępowana przez Page
klasy i Layout
, które są jedynymi dwiema klasami, w Xamarin.Forms których mogą znajdować się elementy podrzędne. Przesłonięte wywołania metody
UpdateChildrenLayout
dlaPage
pochodnych iUpdateChildrenLayout
dlaLayout
pochodnych, które wywołujeLayoutChildren
dlaPage
pochodnych iLayoutChildren
dlaLayout
pochodnych.
LayoutChildren
następnie wywołuje Layout
element podrzędny każdego elementu. Jeśli co najmniej jedno dziecko ma nowe Bounds
ustawienie, zostanie wyzwolone następujące zdarzenie:
LayoutChanged
dlaPage
pochodnych iLayoutChanged
dlaLayout
pochodnych
Ograniczenia i żądania dotyczące rozmiaru
Aby LayoutChildren
inteligentnie zadzwonić Layout
do wszystkich swoich dzieci, musi znać preferowany lub żądany rozmiar dla dzieci. W związku z tym wezwania Layout
do każdego z dzieci są zwykle poprzedzone wezwaniami do
Po opublikowaniu GetSizeRequest
książki metoda została przestarzała i zastąpiona
Metoda Measure
uwzględnia Margin
właściwość i zawiera argument typu MeasureFlag
, który ma dwa elementy członkowskie:
IncludeMargins
None
aby nie uwzględniać marginesów
W przypadku wielu elementów GetSizeRequest
lub Measure
uzyskuje natywny rozmiar elementu z modułu renderowania. Obie metody mają parametry ograniczeń szerokości i wysokości. Na przykład element Label
użyje ograniczenia szerokości, aby określić sposób zawijania wielu wierszy tekstu.
Zarówno GetSizeRequest
, jak i Measure
zwraca wartość typu SizeRequest
, która ma dwie właściwości:
Bardzo często te dwie wartości są takie same, a Minimum
wartość zwykle może być ignorowana.
VisualElement
Definiuje również chronioną metodę podobną do GetSizeRequest
wywoływanej z GetSizeRequest
klasy :
OnSizeRequest
SizeRequest
zwraca wartość
Ta metoda jest teraz przestarzała i zastąpiona:
Każda klasa, która pochodzi z Layout
lub Layout<T>
musi zastąpić OnSizeRequest
lub OnMeasure
. W tym miejscu klasa układu określa swój własny rozmiar, który jest zazwyczaj oparty na rozmiarze jego elementów podrzędnych, które uzyskuje przez wywołanie GetSizeRequest
lub Measure
na elementach podrzędnych. Przed wywołaniem OnSizeRequest
metody lub OnMeasure
GetSizeRequest
lub wprowadź Measure
korekty na podstawie następujących właściwości:
WidthRequest
typdouble
, wpływa naRequest
właściwośćSizeRequest
HeightRequest
typdouble
, wpływa naRequest
właściwośćSizeRequest
MinimumWidthRequest
typdouble
, wpływa naMinimum
właściwośćSizeRequest
MinimumHeightRequest
typdouble
, wpływa naMinimum
właściwośćSizeRequest
Ograniczenia nieskończone
Argumenty ograniczeń przekazane do GetSizeRequest
(lub Measure
) i OnSizeRequest
(lub OnMeasure
) mogą być nieskończone (tj. wartości Double.PositiveInfinity
). SizeRequest
Jednak zwracane z tych metod nie mogą zawierać nieskończonych wymiarów.
Nieskończone ograniczenia wskazują, że żądany rozmiar powinien odzwierciedlać rozmiar naturalny elementu. Wywołania GetSizeRequest
pionowe StackLayout
(lub Measure
) na jego elementach podrzędnych z nieskończonym ograniczeniem wysokości. Poziome wywołania GetSizeRequest
układu stosu (lub Measure
) dla elementów podrzędnych z ograniczeniem nieskończonej szerokości. Wywołania AbsoluteLayout
GetSizeRequest
(lub Measure
) elementów podrzędnych z ograniczeniami nieskończonej szerokości i wysokości.
Zaglądanie wewnątrz procesu
Element ExploreChildSize wyświetla informacje o ograniczeniach i żądaniu rozmiaru dla prostego układu.
Wyprowadzanie z widoku układu<>
Niestandardowa klasa układu pochodzi z klasy Layout<View>
. Ma on dwie obowiązki:
- Zastąpić wywołanie
OnMeasure
Measure
wszystkich elementów podrzędnych układu. Zwraca żądany rozmiar dla samego układu - Zastąpij wywołanie
LayoutChildren
Layout
dla wszystkich elementów podrzędnych układu
Pętla for
or foreach
w tych przesłonięciach powinna pominąć wszystkie elementy podrzędne, których IsVisible
właściwość jest ustawiona na false
.
Połączenie z OnMeasure
usługą nie jest gwarantowane. OnMeasure
nie będzie wywoływany, jeśli element nadrzędny układu zarządza rozmiarem układu (na przykład układem, który wypełnia stronę). Z tego powodu LayoutChildren
nie można polegać na rozmiarach podrzędnych uzyskanych podczas wywołania OnMeasure
. Bardzo często LayoutChildren
trzeba wywołać element Measure
podrzędny układu lub zaimplementować jakąś logikę buforowania rozmiaru (aby omówić później).
Prosty przykład
Przykład VerticalStackDemo zawiera uproszczoną VerticalStack
klasę i pokaz użycia.
Uproszczone pozycjonowanie w pionie i w poziomie
Jedno z zadań, które VerticalStack
należy wykonać, odbywa się podczas zastępowania LayoutChildren
. Metoda używa właściwości podrzędnej HorizontalOptions
, aby określić, jak umieścić element podrzędny w swoim miejscu w VerticalStack
obiekcie . Zamiast tego można wywołać metodę Layout.LayoutChildIntoBoundingRect
statyczną . Ta metoda wywołuje Measure
element podrzędny i używa jej HorizontalOptions
właściwości i VerticalOptions
do umieszczania elementu podrzędnego w określonym prostokątze.
Unieważnienie
Często zmiana właściwości elementu wpływa na sposób wyświetlania tego elementu w układzie. Układ musi zostać unieważniony, aby wyzwolić nowy układ.
VisualElement
definiuje metodę InvalidateMeasure
chronioną , która jest zwykle wywoływana przez program obsługi zmienionych właściwości dowolnej właściwości możliwej do powiązania, której zmiana wpływa na rozmiar elementu. Metoda InvalidateMeasure
uruchamia MeasureInvalidated
zdarzenie.
Klasa Layout
definiuje podobną chronioną metodę o nazwie InvalidateLayout
, która Layout
pochodna powinna wywołać dowolną zmianę, która wpływa na to, w jaki sposób umieszcza i zmienia rozmiar elementów podrzędnych.
Niektóre reguły dotyczące układów kodowania
Właściwości zdefiniowane przez
Layout<T>
pochodne powinny być wspierane przez właściwości możliwe do powiązania, a programy obsługi zmienionej właściwości powinny wywołać metodęInvalidateLayout
.Pochodna
Layout<T>
, która definiuje dołączone powiązane właściwości, powinna zastąpićOnAdded
, aby dodać procedurę obsługi zmienionej właściwości do jej elementów podrzędnych iOnRemoved
usunąć ten program obsługi. Procedura obsługi powinna sprawdzać zmiany w dołączonych właściwościach możliwych do powiązania i reagować, wywołując polecenieInvalidateLayout
.Pochodna
Layout<T>
, która implementuje pamięć podręczną rozmiarów podrzędnych, powinna przesłonićInvalidateLayout
iOnChildMeasureInvalidated
wyczyścić pamięć podręczną po wywołaniu tych metod.
Układ z właściwościami
Klasa WrapLayout
w zestawie Xamarin.FormsBook.Toolkit zakłada, że wszystkie jego elementy podrzędne mają ten sam rozmiar i opakowuje elementy podrzędne z jednego wiersza (lub kolumny) do następnego. Definiuje właściwość, Orientation
na przykład , i ColumnSpacing
RowSpacing
właściwości, takie StackLayout
jak Grid
, i buforuje rozmiary podrzędne.
Przykład PhotoWrap umieszcza WrapLayout
element w obiekcie ScrollView
do wyświetlania zdjęć stockowych.
Brak dozwolonych wymiarów bez ograniczeń!
Xamarin.FormsBiblioteka UniformGridLayout
Book.Toolkit ma na celu wyświetlenie wszystkich swoich elementów podrzędnych w sobie. W związku z tym nie może zajmować się wymiarami bez ograniczeń i zgłasza wyjątek w przypadku napotkania jednego z nich.
W przykładzie photoGrid pokazanoUniformGridLayout
:
Nakładające się elementy podrzędne
Pochodna Layout<T>
może nakładać się na swoje dzieci. Jednak elementy podrzędne są renderowane w ich kolejności w Children
kolekcji, a nie w kolejności, w jakiej są wywoływane ich Layout
metody.
Klasa Layout
definiuje dwie metody, które umożliwiają przenoszenie elementu podrzędnego w kolekcji:
LowerChild
aby przenieść element podrzędny na początek kolekcjiRaiseChild
aby przenieść element podrzędny na koniec kolekcji
W przypadku nakładających się elementów podrzędnych elementy podrzędne na końcu kolekcji wizualnie pojawiają się u góry elementów podrzędnych na początku kolekcji.
Klasa OverlapLayout
w Xamarin.Formsbibliotece Book.Toolkit definiuje dołączoną właściwość, aby wskazać kolejność renderowania, a tym samym umożliwić wyświetlanie jednego z jego elementów podrzędnych na drugim. Przykład StudentCardFile pokazuje to:
Więcej dołączonych właściwości możliwych do powiązania
Klasa CartesianLayout
w Xamarin.Formsbibliotece Book.Toolkit definiuje dołączone powiązane właściwości, aby określić dwie Point
wartości i wartość grubości oraz manipulować BoxView
elementami przypominającymi linie.
W przykładzie UnitCube użyto tej metody do narysowania modułu 3D.
Układ i UkładDo
Pochodna Layout<T>
może wywoływać LayoutTo
zamiast Layout
animować układ. Klasa AnimatedCartesianLayout
to robi, a przykład AnimatedUnitCube demonstruje go.