Flutter: GridView-Widget verwenden
GridView ist ein Widget in Flutter, mit dem Elemente nebeneinander und in Zeilen gestapelt angeordnet werden. Es eignet sich ideal für Galerien, Produktlisten und kartenbasierte Oberflächen.
Live-Demo
Sie können dieses Widget im interaktiven Beispiel unten ausprobieren:
💡 Falls das Beispiel oben nicht lädt, klicken Sie auf DartPad, um es in einem neuen Tab auszuführen.
Grundlegende Verwendung – GridView.count
Ein Raster durch Angabe der Spaltenanzahl erstellen:
GridView.count(
crossAxisCount: 2, // 2 columns
children: [
Container(color: Colors.red, child: Center(child: Text('1'))),
Container(color: Colors.green, child: Center(child: Text('2'))),
Container(color: Colors.blue, child: Center(child: Text('3'))),
Container(color: Colors.orange, child: Center(child: Text('4'))),
],
)Wichtige Eigenschaften
| Eigenschaft | Beschreibung |
|---|---|
crossAxisCount |
Anzahl der Spalten |
mainAxisSpacing |
Vertikaler Abstand |
crossAxisSpacing |
Horizontaler Abstand |
childAspectRatio |
Seitenverhältnis der Elemente |
padding |
Außenabstand |
scrollDirection |
Scrollrichtung |
GridView.extent mit maximaler Breite
Ein Raster durch Angabe der maximalen Breite je Element erstellen:
GridView.extent(
maxCrossAxisExtent: 150, // Each item is maximum 150 pixels wide
mainAxisSpacing: 8,
crossAxisSpacing: 8,
padding: EdgeInsets.all(8),
children: [
Container(color: Colors.purple, child: Center(child: Text('A'))),
Container(color: Colors.pink, child: Center(child: Text('B'))),
Container(color: Colors.cyan, child: Center(child: Text('C'))),
Container(color: Colors.amber, child: Center(child: Text('D'))),
],
)Dynamisches Raster mit GridView.builder
Für dynamisch erzeugte Raster wird die Variante .builder verwendet. Sie bietet eine performante Lösung für große Datenmengen:
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
),
itemCount: 20,
padding: EdgeInsets.all(8),
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
color: Colors.primaries[index % Colors.primaries.length],
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text(
'${index + 1}',
style: TextStyle(color: Colors.white, fontSize: 24),
),
),
);
},
)SliverGridDelegateWithMaxCrossAxisExtent
Dynamisches Raster mit maximaler Breite:
GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 1.5,
),
itemCount: 12,
itemBuilder: (context, index) {
return Card(
color: Colors.teal.shade100,
child: Center(child: Text('Item $index')),
);
},
)Individuell gestaltete Rasterkarten
final List<Map<String, dynamic>> products = [
{'name': 'Product 1', 'price': '\$99', 'icon': Icons.phone_android},
{'name': 'Product 2', 'price': '\$149', 'icon': Icons.laptop},
{'name': 'Product 3', 'price': '\$299', 'icon': Icons.watch},
{'name': 'Product 4', 'price': '\$79', 'icon': Icons.headphones},
];
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 12,
crossAxisSpacing: 12,
childAspectRatio: 0.8,
),
padding: EdgeInsets.all(16),
itemCount: products.length,
itemBuilder: (context, index) {
final product = products[index];
return Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(product['icon'], size: 48, color: Colors.blue),
SizedBox(height: 12),
Text(
product['name'],
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 4),
Text(
product['price'],
style: TextStyle(color: Colors.green, fontSize: 18),
),
SizedBox(height: 8),
ElevatedButton(
onPressed: () {},
child: Text('Buy Now'),
),
],
),
);
},
)Bilderraster (Galerie)
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
),
itemCount: 30,
itemBuilder: (context, index) {
return Image.network(
'https://picsum.photos/200?random=$index',
fit: BoxFit.cover,
);
},
)childAspectRatio verwenden
Das Seitenverhältnis der Elemente anpassen:
GridView.count(
crossAxisCount: 2,
childAspectRatio: 16 / 9, // Wide cards
mainAxisSpacing: 8,
crossAxisSpacing: 8,
children: [
Container(color: Colors.red),
Container(color: Colors.blue),
Container(color: Colors.green),
Container(color: Colors.orange),
],
)Scrollsteuerung
final ScrollController _scrollController = ScrollController();
GridView.builder(
controller: _scrollController,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: 50,
itemBuilder: (context, index) {
return Card(child: Center(child: Text('$index')));
},
)
// Scroll grid to top
_scrollController.animateTo(
0,
duration: Duration(milliseconds: 500),
curve: Curves.easeInOut,
);Zusammenfassung
- GridView.count: Raster mit fester Spaltenanzahl
- GridView.extent: Raster mit maximaler Breite
- GridView.builder: Dynamisches und performantes Raster
- SliverGridDelegate: Steuerung des Rasterlayouts
- childAspectRatio: Seitenverhältnis der Elemente
- mainAxisSpacing / crossAxisSpacing: Einstellungen für Abstände
GridView ist ein hervorragendes Widget für Galerien und kartenbasierte Listen.