5. diel - Pozíciovanie v Xamarin.Forms
V dnešnom C# .NET tutoriálu sa naučíme pozicový elementmi, čo je posledná vec, ktorú musíme poznať pred tým, aby sme tvorili záživnější aplikácie.
Absolútnej a relatívnej pozície
Absolútnej pozície
Niekedy potrebujeme element umiestniť na konkrétnu pozíciu na stránke
(napríklad [89;23]
).
V Xamarin.Forms možné vkladať prvky na absolútnu pozíciu v kontajneri
zvanom AbsoluteLayout
. Keďže sa tento kontajner moc nevyužíva,
tak si ho dnes bližšie popisovať nebudeme.
V ostatných kontajneroch (Grid
, StackLayout
, ...)
si môžeme pomôcť okrajom, čím obsah elementu posunieme:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MyFirstApp.MainPage"> <Grid> <Label Text="Pozdrav z Xamarin.Forms!" VerticalOptions="Start" HorizontalOptions="Start" Margin="89,23,0,0" /> </Grid> </ContentPage>
Prvok <Label>
najprv zarovnáme vľavo hore pomocou
atribútov VerticalOptions
a HorizontalOptions
. Ďalej
mu nastavíme vonkajšie okraje na 89
zľava a 23
zhora atribútom Margin
. Takto vyzerá, že je ovládací prvok na
pozícii [89;23]
, ale v skutočnosti je okolo neho len okraj:
Asi najväčšia nevýhoda používania absolútnych pozícií je, že aplikácia nereaguje na zmenu pomeru strán jednotlivých zariadení, keďže každé zariadenie má inak veľký displej (mobil, tablet, PC). Ďalšou nevýhodou je, že ak nejaký ovládací prvok zväčší svoju veľkosť, musíme ručne tie okolité posunúť, aby sa nám všetko nerozsýpal. To môže byť u väčších aplikácií naozaj veľmi neprehľadné. Preto sa tak aplikácie už nerobia.
Relatívnej pozície
Relatívna pozícia na rozdiel od absolútnej rešpektuje okolitú prvky v
kontajneri. Upravme XAML kód elementu <Label>
tak, aby sa
centroval do elementu, v ktorom je vložený. V našom prípade bude v stredu
kontajnera <Grid>
:
<Label HorizontalOptions="Center" VerticalOptions="Center" Text="Pozdrav z Xamarin.Forms!" />
Keď aplikáciu teraz spustíme na rôznych zariadeniach, Label
je stále uprostred. Asi nemusím hovoriť, že HorizontalOptions
nastavuje vodorovné zarovnanie a VerticalOptions
zvislé:
Okraje
Už sme zistili, že každý element má nejaké okraje. Tým vnútorným sa
hovorí Padding
a tým vonkajším Margin
. Znalci HTML tu budú ako doma:
Každý okraj môžeme nastaviť iný pre rôzne strany alebo ho na všetkých stranách elementu nastaviť na jednu veľkosť.
Vymastíme z aplikácie <Label>
a namiesto neho vložíme
tlačidlo pomocou nasledujúceho XAML kódu:
<Button Text="Tlačítko" HorizontalOptions="Center" VerticalOptions="Center" WidthRequest="100" Margin="100,0,0,0" Padding="0,50,0,0"/>
Výsledok vyzerá takto:
Je vidieť, že hoci je tlačidlo zarovnané doprostred, jeho vonkajší
okraj je na ľavej strane 100
. Túto hodnotu sme nastavili pomocou
Margin
. U vnútorného okraja tlačidla naopak vidíme, že ten
horná je výrazne väčší než ostatné. To je hodnota 50
v
Padding
.
Hodnoty zadávame v poradí: ľavý okraj, horný, pravý, dolný a oddeľujeme je čiarkami. Je možné zadať len jednu hodnotu, ktorá nastaví všetky okraje na rovnakú veľkosť. Rovnako tak môžeme zadať aj 2 hodnoty, jednu pre vodorovné okraje a jednu pre zvislé.
Všimnite si, že sme tlačidle v príklade vyššie zadali šírku pomocou
atribútu WidthRequest
. To sa u tlačidiel zvyčajne robí,
pretože nevyzerá pekne, keď je každé inak širokej podľa dĺžky textu v
ňom. Výška elementov sa potom nastavuje pomocou vlastnosti
HeightRequest
.
Jednotky veľkostí
Xamarin.Forms pracuje s jednotkami, ktoré nie sú závislé na určitom
zariadení (platforme) a každá platforma tak využíva svoje vlastné
jednotky. Ak nastavíme tlačidlu vlastnosť WidthRequest
na
100
, tak Xamarin.Forms vezme toto číslo a akurát ho prevedie na
jednotky používané každú konkrétnu platformou. Jednotky pre jednotlivé
platformy sú:
- iOS:
points
(pts) - Android:
density-independent pixels
(DPS)
Približne platí, že
163 points = 160 density-independent pixels = 1 palec
. Z tohto
vzťahu vyplýva, že musíme počítať s tým, že nikdy nebudú veľkosti na
každej platforme úplne rovnaké. Tlačidlo sa šírkou 100
bude
mať na Androide šírku 100 dps
a na iOS 100 pts
,
teda bude na Androide o kúsoček väčšie.
Pozíciovanie
Spomeňme si ešte niečo málo o pozicovanie ovládacích prvkov. Upravme XAML kód tlačidlá tak, aby vyzeral nasledovne:
<Button Text="Tlačítko" />
Tlačidlo sa roztiahne po celom kontajnera Grid
:
Toto je predvolené správanie prvkov. Ak totiž neurčíme zarovnanie,
predpokladajú sa v nich hodnoty Fill
:
<Button Text="Tlačítko" HorizontalOptions="Fill" VerticalOptions="Fill" />
Do atribútov HorizontalOptions
môžeme nastaviť nasledujúce
hodnoty:
Start
- Zarovnanie na začiatok, teda vľavoCenter
- Zarovnanie na stredEnd
- Zarovnanie na koniec, teda vpravoFill
- Roztiahnutie cez celú šírkuStartAndExpand
CenterAndExpand
EndAndExpand
FillAndExpand
Hodnoty, ktoré obsahujú Expand
, sú určené pre kontajner
StackLayout
. Keď takú hodnotu použijeme na element vo
StackLayout
, tak daný prvok sa bude zarovnávať v čo
najväčšom možnom priestore, ktorý mu StackLayout
poskytuje:
<StackLayout> <Button Text="Tlačítko1" VerticalOptions="Start" HorizontalOptions="Center" WidthRequest="100"/> <Button Text="Tlačítko2" VerticalOptions="FillAndExpand" HorizontalOptions="Center" WidthRequest="100"/> </StackLayout>
Keby sme u druhého tlačidla použili namiesto hodnoty
FillAndExpand
len Fill
, tak sa tlačidlo
neroztáhne:
U VerticalOptions
sú hodnoty rovnaké, akurát hodnota
Start
zarovná element hore a hodnota End
dole.
Pre istotu ešte raz spomeňme, že ovládacie prvky sa zarovnávajú do elementu, v ktorom sú vložené. Tomuto elementu sa hovorí rodičovský (anglicky parent).
Výška a šírka elementov
Pre výšku a šírku elementov používame atribúty
WidthRequest
a HeightRequest
. Pri používaní týchto
atribútov však musíme danému elementu zároveň nastaviť
VerticalOptions
a HorizontalOptions
na nejakú inú
hodnotu ako Fill
alebo FillAndExpand
, pretože tieto
hodnoty majú prednosť pred WidthRequest
a
HeightRequest
. Môžeme tiež nastaviť minimálne alebo maximálne
rozmer pomocou atribútov MinimumWidthRequest
,
MinimumHeightRequest
, MaximumWidthRequest
a
MaximumHeightRequest
.
Grid
a StackLayout
Na koniec dnešnej lekcie si ešte povedzme niečo málo o dvoch základných kontajneroch na ovládacie prvky.
Grid
Doteraz sme Grid
brali ako jednoduchý panel, do ktorého možno
vkladať nejaké ďalšie prvky. Grid
je však už podľa názvu
mriežka a jedná sa tak o najuniverzálnejší kontajner v Xamarin.Forms. V
predvolenom nastavení má len jednu bunku (jeden riadok a jeden stĺpec).
Jednotlivé riadky definujeme pomocou elementov RowDefinitions
a
ColumnDefinitions
:
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="60"/> </Grid.RowDefinitions> <Button Grid.Row="1" Grid.Column="1" Text="Tlačítko"/> </Grid>
V definícii stĺpcov máme 2 stĺpce, u ktorých definujeme ich šírku.
Prvý stĺpec má pevne nastavenú veľkosť na 100
. Druhý stĺpec
má nastavenú hodnotu na *
, vďaka ktorej rovnomerne vyplnia
zvyšné miesto.
Niekedy sa nám hodí upresniť aj túto výplň, napr. Aby bol niektorý
vypĺňajúci stĺpec 2x tak široký ako ostatní alebo polovičný. Zapísali
by sme to ako 2*
alebo 0.5*
.
Ak chceme, aby bol stĺpec široký, ako sú prvky v ňom
obsiahnuté, tak použijeme hodnotu auto
.
U definícií riadku je to obdobné, druhý riadok je vysoký presne
60
, prvý riadok vyplní zvyšok obrazovky.
Všetkým riadkom a stĺpcom môžeme nastaviť rozostupy
pomocou vlastností RowSpacing
a ColumnSpacing
.
Od verzie Xamarin.Forms 4.7 môžeme definícii
jednotlivých riadkov a stĺpcov značne zjednodušiť.
<Grid>
, ktorý sme definovali vyššie, by sa dal ešte
definovať takto:
<Grid ColumnDefinitions="100, *" RowDefinitions="*, 60"> <Button Grid.Row="1" Grid.Column="1" Text="Tlačítko"/> </Grid>
Jednotlivé prvky potom umiestňujeme do mriežky pomocou atribútov
Grid.Row
a Grid.Column
, ktorých východiskové
hodnota 0
. Asi vás neprekvapí, že indexy sú od nuly. Naše
tlačidlo by sa teda umiestnilo do druhého stĺpca a druhého riadku:
V prípade, že chceme, aby prvky zaberali viac riadkov alebo
stĺpcov, tak použijeme atribúty Grid.RowSpan
alebo
Grid.ColumnSpan
, ktorým zadáme počty riadkov alebo stĺpcov.
StackLayout
StackLayout
je kontajner, ktorý jednoducho skladá ovládacie
prvky za seba. Smer, v ktorom tieto prvky bude skladať, môžeme určiť
pomocou atribútu Orientation
. Orientation
je v
predvolenom stave nastavená na hodnotu Vertical
, ale možno ju
nastaviť aj na Horizontal
. Pomocou atribútu Spacing
potom nastavujeme rozostup medzi ovládacími prvkami.