İçeriğe geç / Skip to content / Zum Inhalt
Ahmet Balaman LogoAhmet Balaman

Flutter: GridView-Widget verwenden

Ahmet Balaman
FlutterGridViewWidgetUIGridLayout

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.

Kommentare