Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 5 - Pozicování v Xamarin.Forms

V dnešním C# .NET tutoriálu se naučíme pozicovat elementy, což je poslední věc, kterou musíme znát před tím, abychom tvořili záživnější aplikace.

Absolutní a relativní pozice

Absolutní pozice

Někdy potřebujeme element umístit na konkrétní pozici na stránce (třeba [89;23]).

V Xamarin.Forms lze vkládat prvky na absolutní pozici v kontejneru zvaném AbsoluteLayout. Jelikož se tento kontejner moc nevyužívá, tak si ho dnes blíže popisovat nebudeme.

V ostatních kontejnerech (Grid, StackLayout, ...) si můžeme pomoci okrajem, čímž obsah elementu posuneme:

<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>

Prvek <Label> nejprve zarovnáme vlevo nahoru pomocí atributů VerticalOptions a HorizontalOptions. Dále mu nastavíme vnější okraje na 89 zleva a 23 shora atributem Margin. Takto vypadá, že je ovládací prvek na pozici [89;23], ale ve skutečnosti je kolem něj jen okraj:

Xamarin - Mobilní aplikace v C# .NET

Asi největší nevýhoda používání absolutních pozic je, že aplikace nereaguje na změnu poměru stran jednotlivých zařízení, jelikož každé zařízení má jinak velký displej (mobil, tablet, PC). Další nevýhodou je, že pokud nějaký ovládací prvek zvětší svou velikost, musíme ručně ty okolní posunout, aby se nám všechno nerozsypalo. To může být u větších aplikací opravdu velmi nepřehledné. Proto se tak aplikace již nedělají.

Relativní pozice

Relativní pozice na rozdíl od absolutní respektuje okolní prvky v kontejneru. Upravme XAML kód elementu <Label> tak, aby se centroval do elementu, ve kterém je vložený. V našem případě bude ve středu kontejneru <Grid>:

<Label HorizontalOptions="Center" VerticalOptions="Center" Text="Pozdrav z Xamarin.Forms!" />

Když aplikaci nyní spustíme na různých zařízeních, Label je stále uprostřed. Asi nemusím říkat, že HorizontalOptions nastavuje vodorovné zarovnání a VerticalOptions svislé:

Xamarin - Mobilní aplikace v C# .NET

Okraje

Již jsme zjistili, že každý element má nějaké okraje. Těm vnitřním se říká Padding a těm vnějším Margin. Znalci HTML zde budou jako doma:

Xamarin - Mobilní aplikace v C# .NET

Každý okraj můžeme nastavit jiný pro různé strany nebo ho na všech stranách elementu nastavit na jednu velikost.

Vymažeme z aplikace <Label> a místo něj vložíme tlačítko pomocí následujícího XAML kódu:

<Button Text="Tlačítko" HorizontalOptions="Center" VerticalOptions="Center" WidthRequest="100" Margin="100,0,0,0" Padding="0,50,0,0"/>

Výsledek vypadá takto:

Xamarin - Mobilní aplikace v C# .NET

Je vidět, že ačkoli je tlačítko zarovnané doprostřed, jeho vnější okraj je na levé straně 100. Tuto hodnotu jsme nastavili pomocí Margin. U vnitřního okraje tlačítka naopak vidíme, že ten horní je výrazně větší než ostatní. To je hodnota 50 v Padding.

Hodnoty zadáváme v pořadí: levý okraj, horní, pravý, dolní a oddělujeme je čárkami. Je možné zadat jen jednu hodnotu, která nastaví všechny okraje na stejnou velikost. Stejně tak můžeme zadat i 2 hodnoty, jednu pro vodorovné okraje a jednu pro svislé.

Všimněte si, že jsme tlačítku v příkladu výše zadali šířku pomocí atributu WidthRequest. To se u tlačítek obvykle dělá, jelikož nevypadá hezky, když je každé jinak široké podle délky textu v něm. Výška elementů se poté nastavuje pomocí vlastnosti HeightRequest.

Jednotky velikostí

Xamarin.Forms pracuje s jednotkami, které nejsou závislé na určitém zařízení (platformě) a každá platforma tak využívá své vlastní jednotky. Jestliže nastavíme tlačítku vlastnost WidthRequest na 100, tak Xamarin.Forms vezme toto číslo a akorát ho převede na jednotky používané každou konkrétní platformou. Jednotky pro jednotlivé platformy jsou:

  • iOS: points (pts)
  • Android: density-independent pixels (dps)

Přibližně platí, že 163 points = 160 density-independent pixels = 1 palec. Z tohoto vztahu vyplývá, že musíme počítat s tím, že nikdy nebudou velikosti na každé platformě úplně stejné. Tlačítko se šířkou 100 bude mít na Androidu šířku 100 dps a na iOS 100 pts, tudíž bude na Androidu o kousíček větší.

Pozicování

Zmiňme si ještě něco málo o pozicování ovládacích prvků. Upravme XAML kód tlačítka tak, aby vypadal následovně:

<Button Text="Tlačítko" />

Tlačítko se roztáhne po celém kontejneru Grid:

Xamarin - Mobilní aplikace v C# .NET

Toto je výchozí chování prvků. Pokud totiž neurčíme zarovnání, předpokládají se v nich hodnoty Fill:

<Button Text="Tlačítko" HorizontalOptions="Fill" VerticalOptions="Fill" />

Do atributů HorizontalOptions můžeme nastavit následující hodnoty:

  • Start - Zarovnání na začátek, tedy vlevo
  • Center - Zarovnání na střed
  • End - Zarovnání na konec, tedy vpravo
  • Fill - Roztažení přes celou šířku
  • StartAndExpand
  • CenterAndExpand
  • EndAndExpand
  • FillAndExpand

Hodnoty, které obsahují Expand, jsou určené pro kontejner StackLayout. Když takovou hodnotu použijeme na element ve StackLayout, tak daný prvek se bude zarovnávat v co největším možném prostoru, který 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>

Kdybychom u druhého tlačítka použili namísto hodnoty FillAndExpand jen Fill, tak se tlačítko neroztáhne:

Xamarin - Mobilní aplikace v C# .NET

U VerticalOptions jsou hodnoty stejné, akorát hodnota Start zarovná element nahoru a hodnota End dolů.

Pro jistotu ještě jednou zmiňme, že ovládací prvky se zarovnávají do elementu, ve kterém jsou vložené. Tomuto elementu se říká rodičovský (anglicky parent).

Výška a šířka elementů

Pro výšku a šířku elementů používáme atributy WidthRequest a HeightRequest. Při používání těchto atributů však musíme danému elementu zároveň nastavit VerticalOptions a HorizontalOptions na nějakou jinou hodnotu než Fill nebo FillAndExpand, protože tyto hodnoty mají přednost před WidthRequest a HeightRequest. Můžeme také nastavit minimální nebo maximální rozměr pomocí atributů MinimumWidthRequest, MinimumHeightRequest, MaximumWidthRequest a MaximumHeightRequest.

Grid a StackLayout

Na konec dnešní lekce si ještě řekněme něco málo o dvou základních kontejnerech na ovládací prvky.

Grid

Doposud jsme Grid brali jako jednoduchý panel, do kterého lze vkládat nějaké další prvky. Grid je však již podle názvu mřížka a jedná se tak o nejuniverzálnější kontejner v Xamarin.Forms. Ve výchozím nastavení má jen jednu buňku (jeden řádek a jeden sloupec).

Jednotlivé řádky definujeme pomocí elementů 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 definici sloupců máme 2 sloupce, u kterých definujeme jejich šířku. První sloupec má pevně nastavenou velikost na 100. Druhý sloupec má nastavenou hodnotu na *, díky které rovnoměrně vyplní zbylé místo.

Někdy se nám hodí upřesnit i tuto výplň, např. aby byl některý vyplňující sloupec 2x tak široký než ostatní nebo poloviční. Zapsali bychom to jako 2* nebo 0.5*.

Jestliže chceme, aby byl sloupec široký, jako jsou prvky v něm obsažené, tak použijeme hodnotu auto.

U definic řádku je to obdobné, druhý řádek je vysoký přesně 60, první řádek vyplní zbytek obrazovky.

Všem řádkům a sloupcům můžeme nastavit rozestupy pomocí vlastností RowSpacing a ColumnSpacing.

Od verze Xamarin.Forms 4.7 můžeme definici jednotlivých řádků a sloupců značně zjednodušit. <Grid>, který jsme definovali výše, by se dal ještě definovat takto:

<Grid ColumnDefinitions="100, *"
      RowDefinitions="*, 60">
    <Button Grid.Row="1" Grid.Column="1" Text="Tlačítko"/>
</Grid>

Jednotlivé prvky poté umisťujeme do mřížky pomocí atributů Grid.Row a Grid.Column, jejichž výchozí hodnota je 0. Asi vás nepřekvapí, že indexy jsou od nuly. Naše tlačítko by se tedy umístilo do druhého sloupce a druhého řádku:

Xamarin - Mobilní aplikace v C# .NET

V případě, že chceme, aby prvky zabíraly více řádků nebo sloupců, tak použijeme atributy Grid.RowSpan nebo Grid.ColumnSpan, kterým zadáme počty řádků nebo sloupců.

StackLayout

StackLayout je kontejner, který jednoduše skládá ovládací prvky za sebe. Směr, ve kterém tyto prvky bude skládat, můžeme určit pomocí atributu Orientation. Orientation je ve výchozím stavu nastavená na hodnotu Vertical, ale lze ji nastavit i na Horizontal. Pomocí atributu Spacing poté nastavujeme rozestup mezi ovládacími prvky.

V příští lekci, Debug Xamarin aplikace na Android zařízení a stylovaní, se zaměříme na stylování a další komponenty .NETu.


 

Předchozí článek
Kvíz - Životní cyklus aplikace, XAML v C# .NET Xamarin
Všechny články v sekci
Xamarin - Mobilní aplikace v C# .NET
Přeskočit článek
(nedoporučujeme)
Debug Xamarin aplikace na Android zařízení a stylovaní
Článek pro vás napsal Radek Vymětalík
Avatar
Uživatelské hodnocení:
37 hlasů
...
Aktivity