Shrnutí kapitoly 26. Vlastní rozložení
Poznámka:
Tato kniha byla publikována na jaře roku 2016 a od té doby nebyla aktualizována. Existuje mnoho v knize, která zůstává cenná, ale některé materiály jsou zastaralé a některá témata už nejsou zcela správná nebo úplná.
Xamarin.Forms zahrnuje několik tříd odvozených z Layout<View>
:
StackLayout
,Grid
,AbsoluteLayout
aRelativeLayout
.
Tato kapitola popisuje, jak vytvořit vlastní třídy odvozené od Layout<View>
.
Přehled rozložení
Neexistuje žádný centralizovaný systém, který zpracovává Xamarin.Forms rozložení. Každý prvek je zodpovědný za určení vlastní velikosti a jak se vykreslit v určité oblasti.
Rodiče a děti
Každý prvek, který má děti, je zodpovědný za umístění těchto dětí uvnitř sebe. Jedná se o nadřazený objekt, který nakonec určuje, jakou velikost má podřízené položky mít, na základě velikosti, kterou má k dispozici, a velikosti, kterou má dítě mít.
Určení velikosti a umístění
Rozložení začíná v horní části vizuálního stromu stránkou a pak pokračuje všemi větvemi. Nejdůležitější veřejná metoda v rozložení je Layout
definována .VisualElement
Každý prvek, který je nadřazený jiným prvkům, volá Layout
pro každý z jeho podřízených prvků, aby dítě velikost a umístění relativní k sobě ve formě Rectangle
hodnoty. Tato Layout
volání se šíří prostřednictvím vizuálního stromu.
Volání Layout
vyžaduje, aby se prvek zobrazil na obrazovce a způsobí, že se nastaví následující vlastnosti jen pro čtení. Jsou konzistentní s předávaným Rectangle
metodou:
Před voláním Layout
Height
mají Width
napodobené hodnoty –1.
Volání, které Layout
také aktivuje volání následujících chráněných metod:
SizeAllocated
, která voláOnSizeAllocated
, které lze přepsat.
Nakonec se aktivuje následující událost:
Metoda OnSizeAllocated
je přepsána Page
a Layout
, což jsou pouze dvě třídy, které Xamarin.Forms mohou mít podřízené položky. Přepsaná volání metody
UpdateChildrenLayout
proPage
deriváty aUpdateChildrenLayout
Layout
deriváty, které voláLayoutChildren
derivátůPage
aLayoutChildren
Layout
derivátů.
LayoutChildren
pak volá Layout
každou podřízenou položku prvku. Pokud má aspoň jedno dítě nové Bounds
nastavení, aktivuje se následující událost:
LayoutChanged
proPage
deriváty aLayoutChanged
derivátyLayout
Omezení a požadavky na velikost
Aby LayoutChildren
bylo možné inteligentně volat Layout
všem svým dětem, musí znát upřednostňovanou nebo požadovanou velikost pro děti. Layout
Proto volání pro každou z dětí obecně předchází voláním na
Po publikování GetSizeRequest
knihy byla metoda zastaralá a nahrazena
Metoda Measure
se přizpůsobí Margin
vlastnosti a obsahuje argument typu MeasureFlag
, který má dva členy:
IncludeMargins
None
nezahrnovat okraje
Pro mnoho prvků GetSizeRequest
nebo Measure
získá nativní velikost elementu z jeho rendereru. Obě metody mají parametry pro omezení šířky a výšky. Label
Například použije omezení šířky k určení, jak zalomit více řádků textu.
Obě GetSizeRequest
a Measure
vrátit hodnotu typu SizeRequest
, která má dvě vlastnosti:
Velmi často jsou tyto dvě hodnoty stejné a Minimum
hodnota může být obvykle ignorována.
VisualElement
definuje také chráněnou metodu podobnou GetSizeRequest
té, která je volána z GetSizeRequest
:
OnSizeRequest
vrátí hodnotu.SizeRequest
Tato metoda je nyní zastaralá a nahrazena:
Každá třída, která je odvozena nebo Layout
Layout<T>
musí přepsat OnSizeRequest
nebo OnMeasure
. To je místo, kde třída rozložení určuje svou vlastní velikost, která je obecně založena na velikosti svých podřízených položek, které získává voláním GetSizeRequest
nebo Measure
podřízenými položkami. Před a po volání OnSizeRequest
nebo OnMeasure
GetSizeRequest
nebo Measure
provede úpravy na základě následujících vlastností:
WidthRequest
double
typu , má vliv naRequest
vlastnostSizeRequest
HeightRequest
double
typu , má vliv naRequest
vlastnostSizeRequest
MinimumWidthRequest
double
typu , má vliv naMinimum
vlastnostSizeRequest
MinimumHeightRequest
double
typu , má vliv naMinimum
vlastnostSizeRequest
Nekonečná omezení
Argumenty omezení předané GetSizeRequest
(nebo Measure
) a OnSizeRequest
(nebo OnMeasure
) mohou být nekonečné (tj. hodnoty Double.PositiveInfinity
). SizeRequest
Vrácené z těchto metod však nemohou obsahovat nekonečné dimenze.
Nekonečná omezení označují, že požadovaná velikost by měla odrážet přirozenou velikost prvku. Svislá StackLayout
volání GetSizeRequest
(nebo Measure
) u svých podřízených objektů s omezením nekonečné výšky. Vodorovné volání GetSizeRequest
rozložení zásobníku (nebo Measure
) u podřízených položek s omezením nekonečné šířky. Volání AbsoluteLayout
GetSizeRequest
(nebo Measure
) u svých podřízených položek s nekonečnými omezeními šířky a výšky
Náhled uvnitř procesu
Funkce ExploreChildSize zobrazí informace o požadavcích na omezení a velikost pro jednoduché rozložení.
Odvození ze zobrazení rozložení<>
Vlastní třída rozložení je odvozena od Layout<View>
. Má dvě odpovědnosti:
- Přepište
OnMeasure
voláníMeasure
pro všechny podřízené položky rozložení. Vrácení požadované velikosti pro samotné rozložení - Přepsání
LayoutChildren
pro voláníLayout
všech podřízených položek rozložení
V for
foreach
těchto přepsání by měla přeskočit jakékoli podřízené, jehož IsVisible
vlastnost je nastavena na false
.
Není zaručeno volání OnMeasure
. OnMeasure
nebude volána, pokud nadřazená položka rozložení řídí velikost rozložení (například rozložení, které vyplní stránku). Z tohoto důvodu LayoutChildren
nelze spoléhat na velikosti dětí získané během OnMeasure
volání. Velmi často, LayoutChildren
musí sám volat Measure
podřízené rozložení, nebo můžete implementovat nějaký druh logiky ukládání do mezipaměti (probereme to později).
Jednoduchý příklad
Ukázka VerticalStackDemo obsahuje zjednodušenou VerticalStack
třídu a ukázku jejího použití.
Zjednodušené svislé a vodorovné umístění
Jedna z úloh, které VerticalStack
se musí provést během přepsání LayoutChildren
. Metoda používá podřízenou HorizontalOptions
vlastnost k určení, jak umístit podřízené v jeho slotu v objektu VerticalStack
. Místo toho můžete volat statickou metodu Layout.LayoutChildIntoBoundingRect
. Tato metoda volá Measure
podřízený objekt a používá jeho HorizontalOptions
a VerticalOptions
vlastnosti k umístění podřízeného objektu v zadaném obdélníku.
Neplatnost
Změna vlastnosti elementu často ovlivňuje, jak se tento prvek zobrazuje v rozložení. Aby se aktivovalo nové rozložení, musí být rozložení neplatné.
VisualElement
definuje chráněnou metodu InvalidateMeasure
, která je obecně volána obslužnou rutinou změny vlastnosti jakékoli bindable vlastnosti, jejíž změna ovlivňuje velikost elementu. Metoda InvalidateMeasure
aktivuje MeasureInvalidated
událost.
Třída Layout
definuje podobnou chráněnou metodu s názvem InvalidateLayout
, kterou Layout
by derivát měl volat pro všechny změny, které ovlivňují její pozice a velikosti podřízených položek.
Některá pravidla pro kódování rozložení
Vlastnosti definované
Layout<T>
deriváty by měly být zajištěny vazebnými vlastnostmi a obslužné rutiny změněné vlastností by měly volatInvalidateLayout
.Odvozená
Layout<T>
definice připojených vazebných vlastností by měla přepsatOnAdded
přidání obslužné rutiny změněné vlastností do podřízených položek aOnRemoved
odebrání této obslužné rutiny. Obslužná rutina by měla zkontrolovat změny v těchto připojených vazebných vlastnostech a reagovat volánímInvalidateLayout
.Derivát
Layout<T>
, který implementuje mezipaměť podřízených velikostí, by měla po zavolání těchto metod přepsatInvalidateLayout
aOnChildMeasureInvalidated
vymazat mezipaměť.
Rozložení s vlastnostmi
Třída WrapLayout
v Xamarin.FormsBook.Toolkit předpokládá, že všechny podřízené položky mají stejnou velikost a zabalí děti z jednoho řádku (nebo sloupce) na další. Definuje vlastnost, Orientation
jako je a vlastnosti, jako RowSpacing
StackLayout
ColumnSpacing
Grid
je , a ukládá do mezipaměti podřízené velikosti.
Ukázka PhotoWrap vloží ukázku WrapLayout
ScrollView
pro zobrazení fotografií z fotobanky.
Nejsou povoleny žádné nekontrénované rozměry!
Xamarin.FormsKnihovna UniformGridLayout
Book.Toolkit je určena k zobrazení všech podřízených položek v rámci sebe. Proto nemůže řešit nekontrénované dimenze a vyvolá výjimku, pokud je zjištěna.
Ukázka PhotoGridu ukazuje UniformGridLayout
:
Překrývající se podřízené položky
Derivát Layout<T>
může překrývat své podřízené položky. Podřízené položky jsou však vykresleny v jejich pořadí v Children
kolekci, a ne pořadí, ve kterém jsou volána jejich Layout
metody.
Třída Layout
definuje dvě metody, které umožňují přesunout podřízený objekt v kolekci:
LowerChild
přesunutí podřízeného objektu na začátek kolekceRaiseChild
přesunutí podřízeného objektu na konec kolekce
U překrývajících se podřízených položek se podřízené položky na konci kolekce vizuálně zobrazují nad podřízenými objekty na začátku kolekce.
Třída OverlapLayout
v knihovně Xamarin.FormsBook.Toolkit definuje připojenou vlastnost označující pořadí vykreslování, a proto umožňuje zobrazení jedné z podřízených položek nad ostatními. Ukázka StudentCardFile ukazuje toto:
Další připojené vlastnosti s možností vazby
Třída CartesianLayout
v knihovně Xamarin.FormsBook.Toolkit definuje připojené vazbové vlastnosti, které určují dvě Point
hodnoty a hodnotu tloušťky a manipuluje BoxView
s prvky tak, aby připomínaly čáry.
Ukázka UnitCube používá k vykreslení 3D datové krychle.
Rozložení a rozloženíTo
Odvozený Layout<T>
název může místo Layout
animace rozložení volatLayoutTo
. Třída AnimatedCartesianLayout
to dělá a AnimovanýUnitCube ukázka ukazuje to.