Flutter SK/CZ – #1.7 – PageView & BottomNavigationBar
Úvod
Vitajte na stránke Himdeve development, kde pre Vás pripravujeme tie najlepšie tutoriály, ktoré Vám uľahčia a zefektívnia vývoj mobilných aplikácií.
Cieľ
- V Portfolio obrazovke vytvoriť spodný navigačný bar (BottomNavigationBar) s dvomi kartami na prepínanie medzi dvomi podstránkami portfólia – Portfolio Tutoriály a Portfolio Galéria
- Pridať ďalšiu možnosť prepínania medzi podstránkami portfólia pomocou komponentu PageView
- Implementovať BottomNavigationBar a PageView widgety v spolupráci so Slivermi
Postup
Najskôr otvoríme našu existujúcu aplikáciu z predchádzajúceho tutoriálu a otvoríme portfolio_page.dart súbor. Toto bude náš vstupný súbor pre tento tutoriál.
Je dôležité pripomenúť, že tento tutoriál obzvlásť nadväzuje na predchádzajúci, kde sme vytvorili sliver widgety a naučili sa s nimi pracovať.
V prvej polovici tohto tutoriálu budeme viac menej len pripravovať a upravovať kód tak, aby sme mohli v druhej polovici pracovať priamo len na BottomNavigationBar a PageView widgetoch.
Najskôr si vytvoríme 2 podstránky portfólia.
V priečinku pages vytvoríme súbor portfolio_tutorials_sub_page.dart a v ňom Stateless Widget PortfolioTutorialsSubPage.
Následne v priečinku pages vytvoríme súbor portfolio_gallery_sub_page.dart a v ňom Stateless Widget PortfolioGallerySubPage. V build metóde zatial vrátime len text “Gallery”.
Vrátime sa do portfolio_page.dart súbor a presunieme obsah PortfolioPage triedy do triedy PortfolioTutorialsSubPage. Importneme chýbajúce knižnice. A v build metóde vrátime namiesto Scaffold widgetu priamo CustomScrollView.
PortfolioPage zmeníme zo Stateless Widgetu na Stateful Widget pretože chceme zadefinovať určité premenné a meniť ich hodnoty v tejto triede a to v Stateless Widgete v podstate nejde.
V build metóde vrátime spomínaný Scaffold widget, kde do body atribútu nateraz pridáme PortfolioTutorialsSubPage widget.
Otvoríme PortfolioTutorialsSubPage widget a v build metóde vytiahneme SliverAppBar widget a zadefinujeme mu atribút title a nastavíme ho na hodnotu “Tutorials”.
Tento widget môžeme vytiahnuť do externého súbor portfolio_sliver_app_bar.dart v priečinku components. A následne importnúť v PortfolioTutorialsSubPage widgete.
SliverFixedExtentList widget vytiahneme do metódy _buildSliverContent.
Teraz môžeme skopírovať build metódu a vložiť ju do PortfolioGallerySubPage triedy. Importneme PortfolioSliverAppBar widget a zmeníme mu nadpis na “Gallery”.
Vytvoríme metódu _buildSliverContent, ktorá bude vracať SliverFillRemaining widget, do ktoreho zadefinujeme text “Gallery” hrubým štýlom písma o veľkosti 20 a zacentrujeme ho na stred.
V priečinku pages vytvoríme priečinok portfolio a presunieme do neho naše 3 portfolio triedy aby sme mali prehladnejšiu architektúru projektu. Keďže PortfolioPage widget sa spúšťa klikom na položku v draweri, tak v súbore shop_drawer.dart musíme upraviť import.
Týmto pádom máme kompletne pripravené naše 2 nové podstránky – PortfolioTutorialsSubPage a PortfolioGallerySubPage. A teraz sa naučíme ako zadefinovať spodný navigačný bar – BottomNavigationBar widget a PageView komponent.
BottomNavigationBar
Začneme s BottomNavigationBar widgetom.
Prejdeme do súboru portfolio_page.dart a v triede _PortfolioPageState zadefinujeme list _pages, do ktorého vložíme naše 2 podstránky. A premennú _selectedPage, ktorá bude reprezentovať index zvolenej podstránky. Najskôr ju nastavíme na začiatočnú hodnotu 0.
V Scaffold widgete, pre atribút body pridáme náš list podstránok _pages a vyberieme zvolený index – _selectedPage.
Následne za atribút body, pridáme ďalší Scaffold atribút – bottomNavigationBar, do ktorého vložíme BottomNavigationBar widget.
BottomNavigationBar má niekoľko atribútov, my začneme atribútom items, do ktorého vložíme 2x BottomNavigationBarItem a nastavíme im ikonu a text.
A zvolený index nastavíme na našu premennú _selectedPage pomocou BottomNavigationBar atribútu currentIndex.
Dôležité je upozorniť, že položky v liste _pages musia reprezentovať poradie položiek v BottomNavigationBar atribúte items.
BottomNavigationBar má v sebe implementované už všetky želateľné efekty a animácie. My však musíme dodefinovať preklik medzi týmito položkami – kartami.
Zadefinujeme preto atribút onTap, ktorý má ako argument index kliknutia na kartu. A tento index nastavíme do premennej _selectedPage. Avšak ako už vieme, tak na to aby sa widget prekreslil musíme zavolať setState metódu.
A týmto máme pridaný BottomNavigationBar widget do našej aplikácie.
PageView
Ďalším krokom je pridať PageView. A preto v Scaffold widgete pre atribút body vymažeme momentálny kód a vložíme tam PageView widget. PageView má atribút children, do ktorého vložíme náš list podstránok – _pages.
Týmto funguje slidovanie medzi našimi podstránkami, ale neprepínajú sa karty v našom spodnom navigačnom bare.
Preto prídáme ďalší PageView atribút onPageChanged, ktorý rovnako ako onTap atribút BottomNavigationBar widgetu má index aktuálne zobrazenej stránky a tento index nastavíme našej premennej _selectedPage. A samozrejme to zaobalíme metódou setState.
Týmto pádom nám správne funguje zobrazenie aktivných kárt v spodnom navigačnom bare. Avšak môžeme si všimnúť, že sa nič nestane po kliku na jednotlivé karty BottomNavigationBaru. A to preto, že sme síce spojili zmenu podstránky v PageView s BottomNavigationBarom, ale nie naopak. Čiže musíme spojiť preklik kariet s PageView.
A na to zadefinujeme novú premennú _pageController.
A pridáme túto premennú do PageView atribútu controller. PageController slúži na manipuláciu so stránkami v PageView komponente. V našom prípade využijeme jeho metódu na zmenu stránky v PageView a dokonca využijeme možnosť animácie pomocou metódy _pageController.animateToPage.
V BottomNavigationBare, pre atribút onTap, zavoláme túto metódu PageControllera na zmenu stránky v PageView s animáciu v trvaní 300 milisekúnd a lineárnym typom animácie.
NestedScrollView
V tomto štádiu je vlastne aplikácia plne funkčná. Avšak horný bar (SliverAppBar) má každá stránka vlastný. Keby sme chceli mať spoločný horný bar pre obidve podstránky a PageView zadefinovať len zvyšnému obsahu stránky, tak môžeme na to využiť NestedScrollView widget.
V triedach PortfolioGallerySubPage a PortfolioTutorialsSubPage vymažeme PortfolioSliverAppBar widget z build metódy.
Následne v súbore portfolio_page.dart zaobalíme PageView widget do NestedScrollView widgetu, konkrétne vložíme PageView do NestedScrollView atribútu body.
Ďalším atribútom NestedScrollView widgetu je headerSliverBuilder, v ktorom vytvoríme náš PortfolioSliverAppBar widget.
Teraz však musíme nastaviť nadpis horného baru podľa toho, ktorá podstránka je otvorená. Využijeme na to triedu Tuple2. Do nášho listu _pages, pridáme nadpis k danej podstránke.
Následne môžeme nastaviť nadpis pre PortfolioSliverAppBar podľa indexu aktuálnej podstránky. Z listu _pages vyberiem aktuálnu položku podľa indexu _selectedPage a následne vrátime Tuple premennú item1, ktorá reprezentuje práve nadpis podstránky.
Ešte musíme upraviť atribút children v PageView widgete, kde namiesto _pages, teraz musíme vrátiť konkrétny widget z Tuple listu _pages.
Použijeme na to funkciu map, ktorej musíme zadefinovať návratový typ na <Widget>. Následne vrátime konkrétny widget pomocou Tuple premennej item2. A nakoniec z toho vytvoríme želateľný list widgetov pomocou metódy toList().
Záver
A tým je naša siedma časť tejto prvej série Flutter SK/CZ Tutoriálov ukončená a kompletný zdrojový kód môžete samozrejme nájsť na githube.