Lekcja 5. Layouty II — FlexLayout, AbsoluteLayout, ScrollView, ContentView
ŚredniPo co się tego uczymy?
Grid i StackLayout załatwiają większość formularzy, ale nie wszystko — czasem potrzebujesz elastycznego "zawijania" elementów (jak CSS Flexbox), przewijalnego długiego formularza, albo powtarzalnego fragmentu interfejsu. Ta lekcja kończy przegląd layoutów MAUI, dodatkowo tłumacząc, DLACZEGO w MAUI nie ma klasycznego Canvas znanego z WPF.
Teoria
FlexLayout — elastyczny układ jak CSS Flexbox
Układa elementy w wierszu lub kolumnie, z pełną kontrolą rozmieszczenia i wyrównania — działa bardzo podobnie do Flexboksa z CSS, co ułatwia naukę, jeśli znasz już dział HTML/CSS.
| Właściwość | Opis |
|---|---|
Direction |
Row (poziomo) lub Column (pionowo). |
JustifyContent |
Rozmieszczenie w osi głównej: Start, Center, SpaceBetween, SpaceAround. |
AlignItems |
Wyrównanie w osi poprzecznej: Start, Center, End, Stretch. |
Wrap |
Gdy ustawione na Wrap, elementy automatycznie przechodzą do nowej linii, kiedy zabraknie miejsca — idealne do "kafelków" i kart o zmiennej liczbie elementów. |
Typowe zastosowanie: pasek akcji z równo rozstawionymi przyciskami (JustifyContent="SpaceBetween") albo karta z awatarem, opisem i przyciskiem, która "zawija się" na mniejszych ekranach.
AbsoluteLayout — pozycje "na sztywno" lub procentowo
Pozwala ustawić elementy w konkretnych współrzędnych albo proporcjonalnie do rozmiaru kontenera, przez AbsoluteLayout.LayoutBounds="x,y,szerokość,wysokość" i AbsoluteLayout.LayoutFlags (All, PositionProportional, SizeProportional). Używaj oszczędnie — trudniej niż w Grid/Flex utrzymać responsywność na różnych rozmiarach ekranu. Przydatny głównie, gdy naprawdę musisz "przykleić" element w konkretne miejsce (np. baner na górze zajmujący dokładnie 20% wysokości ekranu).
ScrollView — zawartość przewijalna
Opakowuje JEDEN element potomny (najczęściej layout z wieloma kontrolkami wewnątrz), umożliwiając jego przewijanie. Na telefonie to absolutny obowiązek przy dłuższych formularzach — bez ScrollView zawartość, która nie mieści się na ekranie, zostanie po prostu ucięta, zamiast dać się przewinąć.
ContentView — kontener wielokrotnego użytku
Opakowanie na fragment interfejsu, który chcesz wydzielić albo użyć w kilku miejscach aplikacji — np. panel informacyjny, karta produktu, nagłówek sekcji. To odpowiednik wydzielenia powtarzalnego bloku HTML do osobnego komponentu.
Dlaczego w MAUI nie ma Canvas jak w WPF?
W WPF Canvas pozwalał na dowolne rysowanie i pozycjonowanie po współrzędnych X/Y. W .NET MAUI nie ma bezpośredniego odpowiednika — do rysowania kształtów, wykresów i animacji 2D służy GraphicsView, gdzie rysuje się programistycznie w C# (przypisując obiekt Drawable i implementując metodę Draw), a nie deklaratywnie w XAML. Na egzaminie INF.04 GraphicsView pojawia się bardzo rzadko — traktuj jako ciekawostkę, a do typowych układów zawsze wybieraj Grid, Stack albo Flex.
Ściąga: kiedy którego layoutu użyć?
| Layout | Kiedy używać |
|---|---|
| Grid | Formularze, układ "etykieta + pole", panele 2-3 kolumnowe. |
| Vertical/HorizontalStackLayout | Szybkie układy liniowe: formularze, paski przycisków. |
| FlexLayout | Elastyczne paski akcji, "kafelki", zawijanie elementów. |
| AbsoluteLayout | Rzadko — gdy naprawdę trzeba "przykleić" coś w konkretne miejsce. |
| ScrollView | Długie formularze na telefonie — koniecznie! |
| ContentView | Powtarzalny fragment UI używany w kilku miejscach. |
| GraphicsView | Rysowanie, wykresy — poza typowym zakresem INF.04. |
Schemat
FlexLayout - JustifyContent i AlignItems: Direction="Row", JustifyContent="SpaceBetween": [Anuluj] [Zapisz] [Wyslij] Direction="Row", Wrap="Wrap" (gdy brakuje miejsca): [Element1] [Element2] [Element3] [Element4] [Element5] <- zawiniete do nowej linii
Przykład z życia
Pasek zakładek na dole aplikacji Instagram czy dowolnej aplikacji do zakupów — ikony równo rozstawione na całej szerokości ekranu — to klasyczny FlexLayout z JustifyContent="SpaceBetween". Z kolei długi formularz rejestracyjny w aplikacji bankowej, który przewijasz palcem od góry do dołu, to ScrollView — bez niego pola na dole formularza byłyby całkowicie niedostępne na małym ekranie.
PasekAkcji.xaml (FlexLayout)
<!-- Pasek akcji rowno rozstawiony (FlexLayout) -->
<FlexLayout Direction="Row"
JustifyContent="SpaceBetween"
AlignItems="Center"
Padding="16">
<Button Text="Anuluj" WidthRequest="100" />
<Button Text="Zapisz" WidthRequest="100" />
<Button Text="Wyślij" WidthRequest="100" />
</FlexLayout>
FormularzDlugi.xaml (ScrollView)
<!-- Dlugi formularz opakowany w ScrollView, zeby dalo sie go przewinac -->
<ScrollView>
<VerticalStackLayout Padding="20" Spacing="12">
<Label Text="Dane kontaktowe" FontAttributes="Bold" FontSize="22" />
<Entry Placeholder="Adres e-mail" />
<Entry Placeholder="Telefon" />
<Entry Placeholder="Ulica i numer" />
<Entry Placeholder="Miasto" />
<Entry Placeholder="Kod pocztowy" />
<Button Text="Zapisz" BackgroundColor="RoyalBlue" TextColor="White" />
</VerticalStackLayout>
</ScrollView>
Komentarz i wyjaśnienie kodu
FlexLayout z JustifyContent="SpaceBetween" rozstawia trzy przyciski równomiernie na całej szerokości ekranu — pierwszy przy lewej krawędzi, ostatni przy prawej, środkowy pośrodku, z równymi odstępami. To znacznie prostsze niż ręczne liczenie marginesów.
ScrollView ma DOKŁADNIE JEDNO dziecko — tutaj VerticalStackLayout z pięcioma polami i przyciskiem. Gdyby formularz był krótszy niż ekran, ScrollView zachowuje się neutralnie (nic się nie przewija); gdy jest dłuższy — użytkownik może przesunąć palcem, żeby zobaczyć pola, które nie mieszczą się na ekranie na raz. To jeden z najczęściej pomijanych, a najważniejszych elementów formularzy mobilnych.
Ćwiczenie samodzielne
Zbuduj stronę z paskiem akcji (FlexLayout, 3 przyciski) na górze i długim formularzem (min. 6 pól) w ScrollView poniżej. Uruchom na emulatorze telefonu (nie tabletu) i sprawdź, czy rzeczywiście musisz przewinąć ekran, żeby zobaczyć wszystkie pola i przycisk "Zapisz" na końcu.
Zadania do pracy własnej
Zmień JustifyContent w przykładzie FlexLayout na SpaceAround i SpaceEvenly (jeśli dostępne) i porównaj różnicę w rozstawieniu przycisków.
Zbuduj 'kartę produktu' we FlexLayout z Wrap="Wrap": obrazek, nazwa produktu, cena i przycisk 'Dodaj do koszyka' — sprawdź na emulatorze o małej szerokości ekranu, czy element rzeczywiście się zawija do nowej linii.
Zbuduj ekran ustawień aplikacji: ContentView z powtarzalnym 'wierszem ustawienia' (etykieta + opis po lewej, przełącznik po prawej — użyj HorizontalStackLayout wewnątrz), a następnie użyj tego ContentView (skopiowanego z różnymi danymi) minimum 4 razy w ScrollView, symulując listę ustawień typu 'Powiadomienia', 'Tryb ciemny', 'Lokalizacja', 'Synchronizacja'.
Typowe błędy
Więcej niż jedno dziecko w ScrollView — ScrollView akceptuje TYLKO jeden bezpośredni element potomny; jeśli potrzebujesz kilku, opakuj je w layout (najczęściej VerticalStackLayout albo Grid).
Nadużywanie AbsoluteLayout — sztywne współrzędne X/Y wyglądają dobrze na jednym rozmiarze ekranu i "rozjeżdżają się" na innym; w 95% przypadków lepszym wyborem jest Grid albo Flex.
Szukanie Canvas jak w WPF — MAUI nie ma bezpośredniego odpowiednika; do rysowania służy GraphicsView, ale do UKŁADANIA kontrolek (nie rysowania) zawsze wybieraj Grid/Stack/Flex.
Zapominanie o ScrollView na długich formularzach — jeden z najczęstszych błędów widocznych dopiero na małym ekranie telefonu, niewidoczny na dużym monitorze podczas testów na komputerze.
Nawiązanie do egzaminu zawodowego
To dopełnienie realizacji INF.04.6.2 w zakresie elementów UI. FlexLayout i ScrollView są szczególnie ważne w praktyce — odpowiadają za to, żeby aplikacja mobilna dobrze wyglądała na różnych rozmiarach ekranów, co jest jednym z kluczowych wymagań stawianych aplikacjom mobilnym w podstawie programowej.