Ahmet Balaman LogoAhmet Balaman

Flutter: GridView Widget Kullanımı

personAhmet Balaman
calendar_today
FlutterGridViewWidgetUIGridLayout

GridView, Flutter'da satırlar halinde yan yana veya alt alta öğeler oluşturmak için kullanılan widget'tır. Galeri görünümleri, ürün listeleri ve kart tabanlı arayüzler için idealdir.

Canlı Demo

Aşağıdaki interaktif örnekte bu widget'ı deneyebilirsiniz:

💡 Eğer yukarıdaki örnek açılmazsa, DartPad linkine tıklayarak yeni sekmede çalıştırabilirsiniz.

Temel Kullanım - GridView.count

Sütun sayısını belirleyerek grid oluşturma:

GridView.count(
  crossAxisCount: 2, // 2 sütun
  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'))),
  ],
)

Önemli Özellikler

Özellik Açıklama
crossAxisCount Sütun sayısı
mainAxisSpacing Dikey boşluk
crossAxisSpacing Yatay boşluk
childAspectRatio Çocuk en-boy oranı
padding Dış boşluk
scrollDirection Kaydırma yönü

GridView.extent ile Maksimum Genişlik

Her öğenin maksimum genişliğini belirleyerek grid oluşturma:

GridView.extent(
  maxCrossAxisExtent: 150, // Her öğe maksimum 150 piksel genişliğinde
  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'))),
  ],
)

GridView.builder ile Dinamik Grid

Dinamik olarak grid oluşturmak için .builder alt sınıfından yararlanılır. Büyük veri setleri için performanslı çözüm sunar:

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

Maksimum genişlik ile dinamik grid:

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('Öğe $index')),
    );
  },
)

Özel Tasarımlı Grid Kartları

final List<Map<String, dynamic>> products = [
  {'name': 'Ürün 1', 'price': '₺99', 'icon': Icons.phone_android},
  {'name': 'Ürün 2', 'price': '₺149', 'icon': Icons.laptop},
  {'name': 'Ürün 3', 'price': '₺299', 'icon': Icons.watch},
  {'name': 'Ürün 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('Satın Al'),
          ),
        ],
      ),
    );
  },
)

Resimli Grid (Galeri)

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 Kullanımı

Öğelerin en-boy oranını ayarlama:

GridView.count(
  crossAxisCount: 2,
  childAspectRatio: 16 / 9, // Geniş kartlar
  mainAxisSpacing: 8,
  crossAxisSpacing: 8,
  children: [
    Container(color: Colors.red),
    Container(color: Colors.blue),
    Container(color: Colors.green),
    Container(color: Colors.orange),
  ],
)

Kaydırma Kontrolü

final ScrollController _scrollController = ScrollController();

GridView.builder(
  controller: _scrollController,
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
  ),
  itemCount: 50,
  itemBuilder: (context, index) {
    return Card(child: Center(child: Text('$index')));
  },
)

// Grid'i en üste kaydır
_scrollController.animateTo(
  0,
  duration: Duration(milliseconds: 500),
  curve: Curves.easeInOut,
);

Özet

  • GridView.count: Sabit sütun sayısı ile grid
  • GridView.extent: Maksimum genişlik ile grid
  • GridView.builder: Dinamik ve performanslı grid
  • SliverGridDelegate: Grid düzeni kontrolü
  • childAspectRatio: Öğe en-boy oranı
  • mainAxisSpacing / crossAxisSpacing: Boşluk ayarları

GridView, galeri görünümleri ve kart tabanlı listeler için mükemmel bir widget'tır.

Yorumlar