Flutter SK/CZ – #1.9 – GridView & SliverGrid (Galéria)

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

  1. Vytvoríme galériu obrázkov
  2. Naučíme sa pracovať s komponentami GridView a SliverGrid
  3. Prejdeme si všetkými spôsobmi vytvorenia GridView – GridView.count(), GridView.extent(), GridView(), GridView.custom()
  4. Naučiíme sa spôsob ako komplexne načítať zoznam obrázkov z Flutter priečinka

Postup

Najskôr otvoríme našu existujúcu aplikáciu z predchádzajúceho tutoriálu a otvoríme portfolio_gallery_sub_page.dart súbor. Toto bude náš vstupný súbor pre tento tutoriál.

Pre našu aplikáciu vytvoríme nový priečinok assets. V ňom priečinok images. A do tohto priečinku vložíme niekoľko obrázkov.

assets images structure

Aby naša Flutter aplikácia vedela o týchto obrázkoch, tak otvoríme pubspec.yaml súbor a v sekcii flutter zadefinujeme sekciu assets a v nej našu cestu k obrázkom.

Copy to Clipboard

Teraz sa môžeme vrátiť naspäť do súboru portfolio_gallery_sub_page.dart.

Vytvoríme metódu _loadImagePaths na načítanie ciest k obrázkom v našom priečinku assets/images/.

Copy to Clipboard

AssetManifest.json predstavuje zoznam všetkých assetov v aplikácií. Načítame ho do json stringu manifestContentJson pomocou async-await mechanizmu a následne z neho spravíme mapu manifestMap pomocou príkazu json.decode. Následne vytiahneme z našeho zoznamu len tie assety, ktoré sa nachádzajú v priečinku ‘assets/images/’ a vrátime list ciest k týmto assetom.

Build metóda

Keď máme zoznam ciest k našim obrázkom, zadefinujeme metódu build.

Keďže metóda _loadImagePaths vracia Future objekt, tak použijeme FutureBuilder, kde do future atribútu zadefinujeme túto metódu.

Keď sa získajú dáta, tak zavoláme metódu na vytvorenie obsahu tohto widgetu _buildContent. Ináč vrátime progress bar – CircularProgressIndicator.

GRIDVIEW.COUNT EXPLICIT

CrossAxisCount

Najskôr vrátime v _buildContent metóde GridView pomocou konštruktora GridView.count, ktorý má povinný parameter crossAxisCount. Tento parameter určuje počet widgetov v riadku. 

MainAxisSpacing

Nastavíme aj ďalšie atribúty. Atribút mainAxisSpacing definuje medzeru medzi riadkami.

CrossAxisSpacing

Atribút crossAxisSpacing definuje medzeru medzi stĺpcami.

Padding

Nastavíme aj atribút padding, ktorý definuje medzeru okolo nášho GridView.

Children

A na záver definujeme atribút children, do ktorého vložíme widget obrázku získaného zo zoznamu ciest nami zadefinovaných assetov. Využijeme na to map funkciu, kde vrátime _buildImageWidget metódu s parametrom, konkrétnej cesty k obrázku.

Copy to Clipboard

Image, ClipRRect, BoxShadow

V metóde _buildImageWidget vrátime Container, ktorému nastavíme decoration atribút. Do tohto atribútu vložíme BoxDecoration, v ktorom zadefinujeme tieň okolo Containera pomocou BoxShadow.

BoxShadow má atribúty:

  • color – čo predstavuje farbu tieňu.
  • offset – sem vložíme Offset(2, 2), kde prvé číslo reprezentuje offset na x-ovej osi a druhé offset na y-ovej osi.
  • spreadRadius – je to atribút, ktorý definuje ako veľmi sa má daný Container nafúknuť predtým ako použijeme blur efekt.
  • blurRadius – definuje veľkosť blur efektu.

Ďalším atribútom BoxDecoration je borderRadius, ktorým definujeme zaoblenie nášho tieňa – BoxShadow.

Container má samozrejme atribút child, do ktorého vložíme Image widget s cestou k obrázku a s fit atribútom nastaveným na BoxFit.cover.

Tento Image widget zaobalíme do ClipRRect widgetu aby sme mohli zaobliť rohy našich obrázkov pomocou atribútu borderRadius.

Copy to Clipboard

GRIDVIEW.EXTENT EXPLICIT

Ďalší konštuktor GridView je GridView.extent, ktorý má povinný atribút maxCrossAxisExtent, ktorý predstavuje maximálny rozsah widgetov v priečnej osi.

Rozdiel medzi GridView.count a GridView.extent je v tom, že pri GridView.count zadefinujeme počet widgetov v riadku. Čiže aj keď otočíme zariadenie horizontálne, tak sa widgety síce môžu zväčšiť, ale počet zostane rovnaký. Pri GridView.extent nastavujeme rozsah. To znamená, že pri otočení zariadenia horizontálne, sa viac-menej udrží veľkosť widgetu, ale zväčší sa počet widgetov v riadku. Pri použití GridView.extent konštruktora je layout responzívny.

Copy to Clipboard

GRIDVIEW EXPLICIT EXTENT DELEGATE

GridView.extent tak ako GridView.count je len zjednodušená forma, kde nemusíme definovať delegátov ku GridView. Sú definovaní na pozadí automaticky.

Avšak, je tu možnosť definovať delegátov ku GridView a vtedy využijeme GridView konštruktor len GridView(), ktorý má povinný atribút gridDelegate. Do tohto atribútu vieme vložiť napríklad SliverGridDelegateWithMaxCrossAxisExtent, ktorý sa používa na pozadí pre GridView.extent.

Copy to Clipboard

GRIDVIEW EXPLICIT COUNT DELEGATE

Takisto vieme prerobiť GridView.count na konštruktor GridView(), ktorému do povinného atribútu gridDelegate vložíme SliverGridDelegateWithFixedCrossAxisCount, ktorý sa používa na pozadí pre GridView.count.

Copy to Clipboard

GRIDVIEW BUILDER EXTENT DELEGATE

Doteraz sme definovali explicitný list položiek. Ak však chceme aby sa vytvárali položky postupne ako skrolujeme, čo je samozrejme efektívnejšie, môžeme použiť GridView.builder konštruktor.

Tento konštruktor má povinný atribút znovu gridDelegate, do ktorého vložíme SliverGridDelegateWithMaxCrossAxisExtent

A povinný atribút itemBuilder, ktorý vracia index zobrazenej položky, na ktorý dynamicky vytvoríme daný widget.

Zadefinujeme sem ešte atribút itemCount, ktorý reprezentuje celkový počet dynamicky vytvorených položiek.

Copy to Clipboard

GRIDVIEW CUSTOM EXTENT CHILDREN EXPLICIT DELEGATE

Posledný GridView konštruktor je GridView.custom, ktorý má 2 povinné atribúty. Obidva tieto atribúty sú delegáti. 

GridDelegate je delegát, ktorý riadi rozmiestnenie potomkov v rámci GridView.

A childrenDelegate je delegát, ktorý poskytuje potomkov pre GridView.

Za gridDelegate môže znovu dosadiť napríklad SliverGridDelegateWithMaxCrossAxisExtent s povinným atribútom maxCrossAxisExtent. Alebo SliverGridDelegateWithFixedCrossAxisCount s povinným atribútom crossAxisCount.

Za childrenDelegate dosadíme delegát, ktorý explicitne definuje potomkov a je to SliverChildListDelegate.

Copy to Clipboard

GRIDVIEW CUSTOM EXTENT CHILDREN BUILDER DELEGATE

Znovu keby sme chceli zefektívniť tento proces a vytvárať potomkov v priebehu skrolovania, aby sme ušetrili pamäť, tak môžeme za childrenDelegate dosadiť SliverChildBuilderDelegate.

Copy to Clipboard

SLIVERGRID

GridView widget je vhodný pokiaľ nepracujeme s viacerými sliver-widgetmi. Avšak ak potrebujeme definovať ďalší sliver v CustomScrollView widgete, pre atribút slivers, tak je nutné použiť namiesto GridView, SliverGrid widget

V našom prípade máme horný SliverAppBar, ktorý spolupracuje s GridView len preto, že používame NestedScrollView widget. Ukážeme si však príklad, keby sme mali len CustomScrollView widget, ako by bolo možné zadefinovať SliverGrid tak, aby sme dostali rovnaký efekt ako pri GridView widgete.

SliverGrid je veľmi podobný práve poslednému konštruktoru GridView.custom.

Tiež má 2 povinné atribúty. Prvým je gridDelegate, ktorý funguje presne takisto. A druhým je delegate, ktorý funguje presne takisto ako childrenDelegate pre GridView.custom.

Tentokrát však SliverGrid nemá atribút pre padding.

Copy to Clipboard

Na to aby sme mohli pridať SliverGrid do našej triedy, musíme upraviť build metódu.

Zaobalíme metódu _buildContent do CustomScrollView widgetu, kde pre atribút slivers, zadefinujeme list sliver widgetov a jedným z nich bude práve naša metóda _buildContent, ktorá vracia SliverGrid widget.

Aby sme dosiahli želateľný padding, tak znovu zaobalíme túto metódu ďalším widgetom a tentokrát to bude SliverPadding, ktorému nastavíme želateľný padding.

Copy to Clipboard

Záver

A tým je naša deviata časť tejto prvej série Flutter SK/CZ Tutoriálov ukončená a kompletný zdrojový kód môžete samozrejme nájsť na githube.