Při vývoji aplikací ve Flutteru se můžete setkat s potřebou zobrazit seznam položek jako mřížku. Data můžete zobrazit ve formátu mřížky – tj. s řádky a sloupci – pomocí třídy GridView v aplikaci Flutter.
Použití GridView je nejlepší způsob, jak zkombinovat třídy Row a Column a vytvořit rolovací seznam mřížky. Běžným případem použití je zobrazení seznamu fotografií, například v nativních fotografických aplikacích Google a Apple.
V tomto tutoriálu si ukážeme, jak implementovat GridView do vaší aplikace Flutter. Projdeme si také několik praktických příkladů, abyste viděli GridView v akci.
Podrobně se budeme věnovat následujícímu:
- Co je GridView?
- Vlastnosti GridView
- Zobrazení seznamu s pevným počtem položek
- Zobrazení dlouhého seznamu v GridView
- Vytvoření responzivního zobrazení GridView
Pokud se učíte vizuálně, podívejte se na tento rychlý videonávod:
Co je GridView?
Ve Flutteru je GridView widget, který zobrazuje seznam položek jako 2D pole. Jednoduše řečeno, položky jsou zobrazeny ve formátu tabulky.
Na rozdíl od běžného seznamu, ve kterém jsou položky vykreslovány pouze v jednom směru, GridView vykresluje položky jak horizontálně, tak vertikálně. Obrázek níže znázorňuje, jak se GridView liší od normálního seznamu v aplikaci Flutter:
Zde je minimální kód pro zprovoznění GridView:
GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, ), children: [ Image.network('https://picsum.photos/250?image=1'), Image.network('https://picsum.photos/250?image=2'), Image.network('https://picsum.photos/250?image=3'), Image.network('https://picsum.photos/250?image=4'), ], )
gridDelegate
je vlastnost, která řídí způsob zobrazení položek v seznamu. V našem příkladu má hodnotu SliverGridDelegateWithFixedCrossAxisCount()
s crossAxisCount
nastavte na 3
. To znamená, že chceme zobrazit tři položky vodorovně, pokud je směr posouvání svislý, a tři položky svisle, pokud je směr posouvání vodorovný. Výchozí směr posouvání pro jakýkoli seznam je pouze svislý, takže položky jsou zobrazeny vodorovně.
children
odkazuje na zde uvedený seznam položek. Přijímá seznam všech widgetů, takže můžete na obrazovce zobrazit cokoli, co byste chtěli.
Zde je výstup:
Zde je návod, jak je kód přeložen do uživatelského rozhraní:
Vlastnosti GridView
Pojďme se podívat na některé vlastnosti GridView.
Další skvělé články od LogRocket:
- Nenechte si ujít ani okamžik s The Replay, kurátorským zpravodajem společnosti LogRocket
- Použijte useEffect React k optimalizaci výkonu vaší aplikace
- Přepínání mezi více verzemi Node
- Naučte se animovat aplikaci React pomocí AnimXYZ
- Prozkoumejte Tauri, nový rámec pro vytváření binárních souborů
- Porovnejte NestJS vs. Express.js
- Objevte oblíbené ORM používané v prostředí TypeScript
crossAxisSpacing
Nastavení hodnoty pro tuto vlastnost umožňuje umístit mezeru mezi položky na příčné ose. To znamená, že se prostor zobrazí vodorovně, pokud je směr posouvání svislý.
GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 16), children: [ Image.network('https://picsum.photos/250?image=1'), Image.network('https://picsum.photos/250?image=2'), Image.network('https://picsum.photos/250?image=3'), )
mainAxisSpacing
Hlavní osa odkazuje na osu, ve které se seznam posouvá. Mezera mezi položkami ve směru rolování je dána pomocí mainAxisSpacing
vlastnost.
GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: 16), children: [ Image.network('https://picsum.photos/250?image=1'), Image.network('https://picsum.photos/250?image=2'), Image.network('https://picsum.photos/250?image=3'), )
scrollDirection
Možná budete chtít změnit směr posouvání, když je GridView zobrazen v režimu na šířku. Nastavení scrollDirection
na Axis.horizontal
udělá právě to.
GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, ), scrollDirection: Axis.horizontal, children: [ ... ], )
physics
Tato vlastnost umožňuje nastavit chování posouvání seznamu. Možná nebudete chtít, aby se seznam posouval vůbec. Řekněme, že zobrazujete například obrázkovou koláž. Posouvání můžete zakázat nastavením physics
hodnotu na NeverScrollableScrollPhysics()
. Ve výchozím nastavení používá ClampingScrollPhysics()
pro Android a BouncingScrollPhysics()
pro iOS a vypadá takto:
shrinkWrap
Nastavení shrinkWrap
hodnotu na true
způsobí, že GridView zabere pouze požadované místo k vyplnění položek ve směru posouvání. Výchozí hodnota je false
a rezervuje celou obrazovku, i když položky nejsou v seznamu:
/////shrinkWrap: false, Column( children: [ Expanded( child: GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, ), shrinkWrap: false, children: [... ], ), ), ElevatedButton(onPressed: () {}, child: Text('Close')) ], ) /////shrinkWrap: true, Column( children: [ GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, ), shrinkWrap: true, children: [...], ), ElevatedButton(onPressed: () {}, child: Text('Close')) ], )
Když shrinkWrap
je false
, potřebujeme zabalit GridView do Expanded widgetu tak, aby zabral veškerý dostupný prostor. V opačném případě vyvolá chybu.
Zobrazení seznamu s pevným počtem položek
Flutter má konstruktor pro zobrazení pouze několika položek v GridView s názvem GridView.count()
. Tento konstruktor umožňuje vytvořit GridView s pevným počtem položek. Také to zjednodušuje metodu zadávání počtu položek na křížové ose.
Ukázkový kód vypadá takto:
GridView.count( crossAxisCount: 3, children: [ ... ], )
Počet položek, které se mají zobrazit v křížové ose, je přiřazen k crossAxisCount
vlastnictví. Když se podíváte pozorně, všimnete si, že nepotřebujeme SliverGridDelegateWith FixedCrossAxisCount()
už.
GridView.count()
lze použít k vytvoření uživatelského rozhraní klávesnice, jako je toto:
Zde je kód pro výše uvedený návrh:
GridView.count( crossAxisCount: 3, shrinkWrap: true, padding: EdgeInsets.only(left: 24, right: 24), children: [ DialKey( number: '1', letters: '', ), ... ], )
shrinkWrap
vlastnost je nastavena na true
, což způsobí, že GridView uvolní místo na obrazovce.
DialKey()
je vlastní widget pro zobrazení jediné klávesy. Vypadá to takto:
// DialKey widget class DialKey extends StatelessWidget { final String number; final String letters; DialKey({this.number, this.letters}); @override Widget build(BuildContext context) { return Center( child: Container( width: 80, height: 80, child: FloatingActionButton( onPressed: () {}, backgroundColor: Colors.grey.withOpacity(0.5), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( '$number', style: TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold), ), Text( '$letters', style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold), ) ], ), ), ), ); } }
Zobrazení dlouhého seznamu v GridView
Chcete-li zobrazit dlouhý seznam nebo nekonečný počet položek, které mohou pocházet z databáze, potřebujete GridView.builder()
konstruktor.
Zde je ukázkový kód:
GridView.builder( itemCount: 100, itemBuilder: (context, index) => ItemTile(index), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, ), )
itemCount
představuje počet položek. To pomáhá GridView odhadnout maximální rozsah posouvání.
itemBuilder
vytvoří daný widget na základě aktuálního indexu.
Zkusme vytvořit záznam produktu takto:
Kód je následující:
GridView.builder( itemCount: 100, itemBuilder: (context, index) => ItemTile(index), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, childAspectRatio: 2, ), ) class ItemTile extends StatelessWidget { final int itemNo; const ItemTile( this.itemNo, ); @override Widget build(BuildContext context) { final Color color = Colors.primaries[itemNo % Colors.primaries.length]; return Padding( padding: const EdgeInsets.all(8.0), child: ListTile( tileColor: color.withOpacity(0.3), onTap: () {}, leading: Container( width: 50, height: 30, color: color.withOpacity(0.5), child: Placeholder( color: color, ), ), title: Text( 'Product $itemNo', key: Key('text_$itemNo'), ), ), ); } }
Jedna důležitá věc, kterou je třeba ve výše uvedeném kódu poznamenat, je childAspectRatio
vlastnictví. To lze použít k nastavení výšky položek, jak je znázorněno níže:
Vytvoření responzivního zobrazení GridView
S vydáním Flutter 2.0 nyní můžete kromě mobilních aplikací vyvíjet aplikace pro web a desktop. Při vytváření aplikací pro různé platformy se chcete ujistit, že uspokojíte uživatele webu tím, že vytvoříte nejlepší možnou uživatelskou zkušenost. V tomto případě zobrazení více položek na mřížce, když je zobrazena na větší obrazovce, může znamenat dlouhou cestu ke zlepšení uživatelského rozhraní pro uživatele webu.
Upravme předchozí kód tak, aby zobrazoval více položek na křížové ose při zobrazení na větší obrazovce:
//Before GridView.builder( itemCount: 100, itemBuilder: (context, index) => ItemTile(index), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, childAspectRatio: 2, ), ) //After LayoutBuilder(builder: (context, constraints) { return GridView.builder( itemCount: 100, itemBuilder: (context, index) => ItemTile(index), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: constraints.maxWidth > 700 ? 4 : 1, childAspectRatio: 5, ), ); })
Zabalte GridView do LayoutBuilder
. LayoutBuilder
poskytuje constraints
, pomocí kterého lze určit šířku a výšku. Pomocí omezení můžeme vytvořit různá uživatelská rozhraní.
V našem příkladu, kdykoli se rozlišení obrazovky změní na šířku 700 nebo větší, zobrazíme na křížové ose čtyři položky.
Zde je výstup:
Závěr
Pokud jste se dostali až sem, měli byste mít všechny potřebné dovednosti a základní znalosti k vytváření komplexních a poutavých seznamů mřížek ve Flutteru pomocí GridView.
Úplný kód použitý v tomto příkladu je k dispozici na GitHubu.