Ahmet Balaman LogoAhmet Balaman

Flutter: Spacer Widget ile Esnek Boşluklar

personAhmet Balaman
calendar_today
FlutterSpacerLayoutFlexRowColumn

Spacer, Row veya Column içindeki widget'lar arasında esnek boşluklar oluşturmak için kullanılan özel bir widget'tır. En az iki widget arasında "sonsuz" boşluk yaratır.

Spacer Nedir?

Spacer, içinde bulunduğu Flex container'da (Row, Column) mevcut boş alanı kaplamak için genişler. Birden fazla widget arasında boşluk dağıtmak için idealdir.

Temel Kullanım

Row içinde Spacer

Row(
  children: [
    Text('Sol'),
    Spacer(),
    Text('Sağ'),
  ],
)

Bu örnekte "Sol" ve "Sağ" metinleri arasındaki tüm boş alan Spacer tarafından doldurulur, böylece metinler iki uca yaslanır.

Column içinde Spacer

Column(
  children: [
    Text('Üst'),
    Spacer(),
    Text('Alt'),
  ],
)

"Üst" ve "Alt" metinleri arasında maksimum dikey boşluk oluşturulur.

Birden Fazla Spacer

Birden fazla Spacer kullanarak boşlukları eşit şekilde dağıtabilirsiniz:

Row(
  children: [
    Text('Sol'),
    Spacer(),
    Text('Orta'),
    Spacer(),
    Text('Sağ'),
  ],
)

İki Spacer eşit boşluk paylaşır, üç metin eşit aralıklarla dağılır.

Flex Parametresi

Spacer'ın flex parametresi ile boşlukların oranını ayarlayabilirsiniz:

Row(
  children: [
    Text('Sol'),
    Spacer(flex: 1), // 1 birim boşluk
    Text('Orta'),
    Spacer(flex: 2), // 2 birim boşluk
    Text('Sağ'),
  ],
)

İkinci Spacer, birinci Spacer'ın iki katı kadar alan kaplar. "Orta" ile "Sağ" arasındaki boşluk, "Sol" ile "Orta" arasındaki boşluktan iki kat fazla olur.

Flex Oranları

Column(
  children: [
    Container(height: 50, color: Colors.red),
    Spacer(flex: 1), // 1/4 boşluk
    Container(height: 50, color: Colors.blue),
    Spacer(flex: 3), // 3/4 boşluk
    Container(height: 50, color: Colors.green),
  ],
)

Toplam flex değeri 4 (1+3), ilk boşluk %25, ikinci boşluk %75 alan kaplar.

Pratik Kullanım Örnekleri

Örnek 1: App Bar Benzeri Düzen

Row(
  children: [
    IconButton(icon: Icon(Icons.menu), onPressed: () {}),
    Text('Başlık', style: TextStyle(fontSize: 20)),
    Spacer(),
    IconButton(icon: Icon(Icons.search), onPressed: () {}),
    IconButton(icon: Icon(Icons.more_vert), onPressed: () {}),
  ],
)

Örnek 2: Kart Alt Kısmı

Row(
  children: [
    Text('Fiyat: ₺99'),
    Spacer(),
    ElevatedButton(
      onPressed: () {},
      child: Text('Satın Al'),
    ),
  ],
)

Örnek 3: Dikey Düzen

Column(
  children: [
    // Üst içerik
    Padding(
      padding: EdgeInsets.all(16),
      child: Text('Üst İçerik'),
    ),
    
    Spacer(), // Ortada boşluk
    
    // Alt buton
    Padding(
      padding: EdgeInsets.all(16),
      child: ElevatedButton(
        onPressed: () {},
        child: Text('Alt Buton'),
      ),
    ),
  ],
)

Örnek 4: Üç Bölümlü Düzen

Row(
  children: [
    Icon(Icons.arrow_back),
    Spacer(flex: 1),
    Text('Başlık'),
    Spacer(flex: 1),
    Icon(Icons.settings),
  ],
)

Başlık tam ortada, ikonlar iki yanda eşit uzaklıkta.

Spacer vs SizedBox

SizedBox - Sabit Boşluk

Row(
  children: [
    Text('Sol'),
    SizedBox(width: 20), // Her zaman 20 piksel
    Text('Sağ'),
  ],
)
  • Sabit boyutta boşluk
  • Ekran boyutu değişse bile aynı kalır

Spacer - Esnek Boşluk

Row(
  children: [
    Text('Sol'),
    Spacer(), // Mevcut tüm boşluğu kaplar
    Text('Sağ'),
  ],
)
  • Mevcut alana göre genişler
  • Responsive düzenlerde kullanışlı

Spacer vs Expanded

Spacer aslında Expanded(child: SizedBox()) ile aynı işlevi görür:

Spacer Kullanımı

Row(
  children: [
    Text('Sol'),
    Spacer(),
    Text('Sağ'),
  ],
)

Expanded ile Eşdeğeri

Row(
  children: [
    Text('Sol'),
    Expanded(child: SizedBox()),
    Text('Sağ'),
  ],
)

Fark: Spacer daha okunabilir ve niyeti daha açık gösterir. Sadece boşluk için Spacer, içerik için Expanded kullanın.

Spacer ile Expanded Birlikte

Row(
  children: [
    Text('Sabit'),
    Spacer(flex: 1),
    Expanded(
      flex: 2,
      child: Container(
        color: Colors.blue,
        child: Text('Genişleyen'),
      ),
    ),
    Spacer(flex: 1),
    Text('Sabit'),
  ],
)

Boşluklar ve genişleyen içerik birlikte oransal olarak paylaşılır.

⚠️ Önemli Uyarılar

1. Sonsuz Boyutta Kullanmayın

Spacer, sonsuz boyutta ekranlarda ASLA kullanılmamalıdır:

// ❌ YANLIŞ - Hata verir
ListView(
  children: [
    Text('Üst'),
    Spacer(), // HATA! ListView sonsuz yüksekliğe sahip
    Text('Alt'),
  ],
)

Neden? ListView gibi scrollable widget'lar sonsuz boyuta sahiptir. Spacer bu durumda ne kadar genişlemesi gerektiğini bilemez.

2. Sınırlı Alan İçinde Kullanın

// ✅ DOĞRU
Container(
  height: 300, // Sınırlı yükseklik
  child: Column(
    children: [
      Text('Üst'),
      Spacer(),
      Text('Alt'),
    ],
  ),
)

3. SingleChildScrollView ile Dikkatli Olun

// ❌ YANLIŞ
SingleChildScrollView(
  child: Column(
    children: [
      Text('Üst'),
      Spacer(), // Sorun çıkarabilir
      Text('Alt'),
    ],
  ),
)

Çözüm: ScrollView içinde Spacer yerine SizedBox kullanın:

// ✅ DOĞRU
SingleChildScrollView(
  child: Column(
    children: [
      Text('Üst'),
      SizedBox(height: 100), // Sabit boşluk
      Text('Alt'),
    ],
  ),
)

En Az İki Widget Gerekir

Spacer tek başına veya tek widget ile kullanılamaz:

// ❌ YANLIŞ
Row(
  children: [
    Spacer(),
    Text('Tek widget'),
  ],
)
// ✅ DOĞRU
Row(
  children: [
    Text('Sol'),
    Spacer(),
    Text('Sağ'),
  ],
)

mainAxisAlignment ile Karşılaştırma

Spacer yerine bazı durumlarda mainAxisAlignment kullanabilirsiniz:

mainAxisAlignment.spaceBetween

Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    Text('Sol'),
    Text('Sağ'),
  ],
)

Spacer Eşdeğeri

Row(
  children: [
    Text('Sol'),
    Spacer(),
    Text('Sağ'),
  ],
)

Fark: Spacer daha esnek, oranlar ile oynayabilirsiniz. mainAxisAlignment daha basit ve önceden tanımlıdır.

Ne Zaman Kullanmalı?

Spacer kullanın:

  • İki veya daha fazla widget arasında esnek boşluk istediğinizde
  • Boşluk oranlarını kontrol etmek istediğinizde
  • Widget'ları iki uca yerleştirmek istediğinizde
  • Sınırlı boyutlu container içinde çalışırken

Spacer kullanmayın:

  • ListView, GridView gibi scrollable widget'larda
  • SingleChildScrollView içinde
  • Sonsuz boyutlu alanlarda
  • Sabit boşluk yeterli olduğunda (SizedBox kullanın)

Özet

Spacer:

  • Row ve Column içinde esnek boşluk oluşturur
  • flex parametresi ile oransal boşluk dağıtır
  • En az iki widget arasında kullanılmalıdır
  • Sonsuz boyutlu scrollable widget'larda kullanılmamalıdır
  • Expanded(child: SizedBox()) ile eşdeğerdir
  • Boşluk için tasarlanmıştır, içerik için Expanded kullanın

Altın Kural: Spacer'ı sadece sınırlı boyutlu (bounded) Flex container'larda (Row, Column) kullanın. Scrollable widget'larda kesinlikle kullanmayın!