Lekcja 4. Layouty I — VerticalStackLayout, HorizontalStackLayout, Grid
ŚredniPo co się tego uczymy?
Layout to kontener, który decyduje, jak rozmieszczone są kontrolki na ekranie — bez niego przyciski i pola tekstowe nakładałyby się na siebie. .NET MAUI oferuje więcej rodzajów layoutów niż WPF, bo musi dobrze działać na bardzo różnych rozmiarach ekranów (mały telefon, duży tablet). Zaczynamy od dwóch najczęściej używanych: układów stosowych i Grid.
Teoria
VerticalStackLayout — elementy jeden pod drugim
Układa elementy w pionie, jeden pod drugim. Idealny do formularzy, list, ekranów logowania.
| Właściwość | Opis |
|---|---|
Padding |
Odstęp od krawędzi kontenera do jego zawartości. |
Spacing |
Odstęp MIĘDZY kolejnymi elementami wewnątrz layoutu. |
HorizontalStackLayout — elementy obok siebie
Układa elementy poziomo. Idealny do przycisków, ikon, pasków nawigacji. Ma te same właściwości Padding/Spacing co wersja pionowa — różni się tylko kierunkiem układania.
Oba układy stosowe można ze sobą łączyć — np. pionowy formularz, a na dole poziomy rządek przycisków "Anuluj"/"Zapisz". To bardzo częsty wzorzec w prostych ekranach mobilnych.
Uwaga wydajnościowa: StackLayout (i jego warianty) przy BARDZO dużej liczbie elementów (setki) może zacząć działać wolniej — do długich list zawsze używaj CollectionView (osobna lekcja), a nie stosu pełnego pojedynczych kontrolek.
Grid — układ w siatce (wiersze i kolumny)
Najbardziej precyzyjny layout: definiujesz wiersze i kolumny, a potem wskazujesz, w której "komórce" ma się znaleźć każda kontrolka. Idealny do formularzy typu "etykieta + pole", kart, paneli wielokolumnowych.
| Właściwość | Opis |
|---|---|
Grid.RowDefinitions / Grid.ColumnDefinitions |
Definicja liczby i rozmiaru wierszy/kolumn. |
Height="Auto" / Width="Auto" |
Wiersz/kolumna zajmuje tyle miejsca, ile potrzebuje jej zawartość. |
Height="*" / Width="*" |
Wiersz/kolumna elastycznie wypełnia resztę dostępnego miejsca (może być też 2*, 3* dla proporcji). |
Grid.Row / Grid.Column |
Ustawiane na DZIECKU Grid — wskazuje, w której komórce ma się znaleźć. |
Grid.ColumnSpan / Grid.RowSpan |
Rozciąga element na kilka kolumn/wierszy naraz (np. przycisk na całą szerokość formularza). |
Wskazówka pod egzamin: Grid to najczęstszy wybór w zadaniach egzaminacyjnych z formularzami — jeśli zadanie wymaga precyzyjnego ułożenia etykiet i pól w kolumnach, zawsze zaczynaj od Grid.
Schemat
Layouty stosowe vs Grid: VerticalStackLayout: HorizontalStackLayout: Grid (2 wiersze x 2 kolumny): [Label 1] [Btn1][Btn2][Btn3] [Label][Entry ] [Label 2] [Label][Entry ] [Label 3] [ Button (span)]
Przykład z życia
Formularz logowania w niemal każdej aplikacji mobilnej to VerticalStackLayout (pola jedno pod drugim) z HorizontalStackLayout na dole (przyciski "Anuluj"/"Zaloguj" obok siebie) — dokładnie ten sam wzorzec, który widziałeś w formularzach WPF, tylko inne nazwy klas i właściwości.
RejestracjaPage.xaml (StackLayout)
<!-- Formularz rejestracji: VerticalStackLayout + HorizontalStackLayout -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="LayoutyApp.RejestracjaPage">
<VerticalStackLayout Padding="20" Spacing="15">
<Label Text="Rejestracja"
FontSize="24"
FontAttributes="Bold"
HorizontalOptions="Center" />
<Entry x:Name="PoleEmail" Placeholder="E-mail" />
<Entry x:Name="PoleHaslo" Placeholder="Hasło" IsPassword="True" />
<!-- Poziomy rzad przyciskow na dole formularza -->
<HorizontalStackLayout Spacing="10" HorizontalOptions="Center">
<Button Text="Anuluj" BackgroundColor="Gray" TextColor="White" WidthRequest="100" />
<Button Text="Zarejestruj" BackgroundColor="RoyalBlue" TextColor="White" WidthRequest="100" />
</HorizontalStackLayout>
</VerticalStackLayout>
</ContentPage>
RejestracjaPage.xaml (wersja Grid)
<!-- Ten sam formularz zbudowany w Grid - precyzyjne wiersze/kolumny -->
<Grid Padding="20" RowSpacing="12" ColumnSpacing="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="E-mail:" Grid.Row="0" Grid.Column="0" VerticalTextAlignment="Center" />
<Entry Placeholder="podaj e-mail" Grid.Row="0" Grid.Column="1" />
<Label Text="Hasło:" Grid.Row="1" Grid.Column="0" VerticalTextAlignment="Center" />
<Entry IsPassword="True" Placeholder="********" Grid.Row="1" Grid.Column="1" />
<!-- ColumnSpan="2" rozciaga przycisk na cala szerokosc formularza -->
<Button Text="Zarejestruj"
Grid.Row="2" Grid.ColumnSpan="2"
BackgroundColor="RoyalBlue" TextColor="White" />
</Grid>
Komentarz i wyjaśnienie kodu
Pierwszy przykład (RejestracjaPage.xaml) używa VerticalStackLayout jako głównego kontenera formularza — proste, liniowe ułożenie: nagłówek, dwa pola, i na końcu HorizontalStackLayout z dwoma przyciskami obok siebie. To najszybszy sposób budowania prostych formularzy.
Drugi przykład pokazuje TEN SAM formularz zbudowany w Grid: trzy wiersze (dwa Auto — dopasowane do zawartości pól, jeden * — reszta miejsca) i dwie kolumny (Auto dla etykiet, * dla pól tekstowych). Przycisk na dole ma Grid.ColumnSpan="2", więc rozciąga się na obie kolumny — dzięki temu jest wyśrodkowany względem całego formularza, a nie tylko drugiej kolumny. Grid daje więcej kontroli nad precyzyjnym wyrównaniem etykiet i pól niż proste układy stosowe.
Ćwiczenie samodzielne
Zbuduj OBA warianty formularza rejestracji (StackLayout i Grid) w osobnych stronach ContentPage tego samego projektu. Uruchom na emulatorze i porównaj efekt — powinny wyglądać niemal identycznie, mimo zupełnie innego kodu XAML.
Zadania do pracy własnej
Dodaj do formularza (dowolna wersja) trzecie pole Entry na potwierdzenie hasła.
Rozbuduj wersję z Grid o dodatkowy wiersz z polem 'Imię' i 'Nazwisko' ułożonymi OBOK SIEBIE w jednym wierszu (dwie dodatkowe kolumny albo zagnieżdżony HorizontalStackLayout w jednej komórce Grid).
Zbuduj ekran profilu użytkownika: Grid z 3 wierszami (nagłówek na całą szerokość przez ColumnSpan, sekcja danych w 2 kolumnach etykieta+wartość, i stopka na całą szerokość), a wewnątrz sekcji danych zagnieźdź VerticalStackLayout z co najmniej 4 parami etykieta/wartość (Imię, Email, Telefon, Miasto).
Typowe błędy
Używanie StackLayout do bardzo długich list — setki elementów w jednym VerticalStackLayout znacząco spowalniają aplikację; do list danych zawsze używaj CollectionView.
Zapominanie o RowDefinitions/ColumnDefinitions — bez jawnej definicji Grid ma domyślnie jeden wiersz i jedną kolumnę, więc wszystkie dzieci nałożą się na siebie w jednej komórce.
Mylenie Auto z * — Auto dopasowuje się do zawartości (może być za wąskie dla długiego tekstu), * zajmuje całą dostępną resztę — dobór złej wartości psuje układ na różnych rozmiarach ekranu.
Brak testowania na różnych rozmiarach ekranu — układ, który wygląda dobrze na dużym telefonie, może się "rozjechać" na małym — zawsze warto sprawdzić na kilku wirtualnych urządzeniach.
Nawiązanie do egzaminu zawodowego
To realizacja INF.04.6.2 w zakresie elementów UI i XAML. VerticalStackLayout, HorizontalStackLayout i Grid to podstawowe narzędzia budowy każdego ekranu aplikacji mobilnej — pojawią się w praktycznie każdym kolejnym zadaniu tego działu.