Ahmet Balaman LogoAhmet Balaman

Flutter: Expanded Widget ile Alan Genişletme

personAhmet Balaman
calendar_today
FlutterExpandedFlexLayoutRowColumn

Expanded, Row veya Column içindeki bir widget'ı mevcut tüm boş alanı kaplayacak şekilde genişletir. Spacer'a benzer ama önemli farkı, içinde görünür içerik barındırabilmesidir.

Expanded Nedir?

Expanded, Flex container'larda (Row, Column) çocuğunu mevcut boş alanı dolduracak şekilde genişletir. Spacer boşluk için kullanılırken, Expanded içerik için kullanılır.

Canlı Demo: Expanded Widget Örnekleri

Expanded ve flex kullanımlarını interaktif olarak deneyin:

Temel Kullanım

Row içinde Expanded

Row(
  children: [
    Container(width: 50, color: Colors.red),
    Expanded(
      child: Container(color: Colors.blue, child: Text('Genişledim')),
    ),
    Container(width: 50, color: Colors.green),
  ],
)

Mavi container, kırmızı ve yeşil container'lardan sonra kalan tüm alanı kaplar.

Column içinde Expanded

Column(
  children: [
    Container(height: 50, color: Colors.red),
    Expanded(
      child: Container(color: Colors.blue, child: Text('Genişledim')),
    ),
    Container(height: 50, color: Colors.green),
  ],
)

Mavi container, dikeyde kalan tüm alanı kaplar.

Flex Parametresi

Birden fazla Expanded widget'ı kullanıldığında, flex parametresi ile alanın nasıl paylaşılacağını belirleyebilirsiniz:

Row(
  children: [
    Expanded(
      flex: 1,
      child: Container(color: Colors.red, child: Text('1 birim')),
    ),
    Expanded(
      flex: 2,
      child: Container(color: Colors.blue, child: Text('2 birim')),
    ),
    Expanded(
      flex: 1,
      child: Container(color: Colors.green, child: Text('1 birim')),
    ),
  ],
)

Toplam flex: 1+2+1 = 4

  • Kırmızı: 1/4 (%25) alan kaplar
  • Mavi: 2/4 (%50) alan kaplar
  • Yeşil: 1/4 (%25) alan kaplar

Varsayılan Flex Değeri

Flex parametresi belirtilmezse varsayılan değer 1'dir:

Row(
  children: [
    Expanded(child: Container(color: Colors.red)), // flex: 1
    Expanded(child: Container(color: Colors.blue)), // flex: 1
  ],
)

İki container eşit alan kaplar (%50 - %50).

Pratik Kullanım Örnekleri

Örnek 1: Tam Genişlik Buton

Column(
  children: [
    Expanded(
      child: Container(
        color: Colors.blue.shade50,
        child: Center(child: Text('İçerik Alanı')),
      ),
    ),
    Container(
      width: double.infinity,
      child: ElevatedButton(
        onPressed: () {},
        child: Text('Alt Buton'),
      ),
    ),
  ],
)

Örnek 2: İki Sütunlu Düzen

Row(
  children: [
    Expanded(
      flex: 2,
      child: Container(
        color: Colors.blue.shade100,
        child: Center(child: Text('Ana İçerik')),
      ),
    ),
    Expanded(
      flex: 1,
      child: Container(
        color: Colors.grey.shade200,
        child: Center(child: Text('Yan Panel')),
      ),
    ),
  ],
)

Ana içerik %66, yan panel %33 alan kaplar.

Örnek 3: Kart İçinde Form

Card(
  child: Padding(
    padding: EdgeInsets.all(16),
    child: Row(
      children: [
        Icon(Icons.person),
        SizedBox(width: 12),
        Expanded(
          child: TextField(
            decoration: InputDecoration(
              hintText: 'Adınızı girin',
              border: OutlineInputBorder(),
            ),
          ),
        ),
      ],
    ),
  ),
)

TextField, icon'dan sonra kalan tüm alanı kaplar.

Örnek 4: Liste Öğesi Düzeni

Row(
  children: [
    CircleAvatar(child: Text('A')),
    SizedBox(width: 12),
    Expanded(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('Ahmet Balaman', style: TextStyle(fontWeight: FontWeight.bold)),
          Text('Flutter Developer', style: TextStyle(color: Colors.grey)),
        ],
      ),
    ),
    Icon(Icons.more_vert),
  ],
)

Örnek 5: Alt Üst Düzen (Sticky Footer)

Column(
  children: [
    Expanded(
      child: SingleChildScrollView(
        child: Padding(
          padding: EdgeInsets.all(16),
          child: Text('Uzun içerik buraya gelir...'),
        ),
      ),
    ),
    Container(
      color: Colors.blue,
      padding: EdgeInsets.all(16),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          ElevatedButton(onPressed: () {}, child: Text('İptal')),
          ElevatedButton(onPressed: () {}, child: Text('Tamam')),
        ],
      ),
    ),
  ],
)

Expanded vs Flexible

Expanded aslında Flexible(fit: FlexFit.tight) ile aynıdır:

Expanded

Row(
  children: [
    Expanded(
      child: Container(color: Colors.blue),
    ),
  ],
)

Flexible (Eşdeğeri)

Row(
  children: [
    Flexible(
      fit: FlexFit.tight,
      child: Container(color: Colors.blue),
    ),
  ],
)

Fark:

  • Expanded: Her zaman tüm alanı kaplar (tight)
  • Flexible: İsteğe bağlı genişleyebilir (loose)

Detaylı karşılaştırma için flutter-expanded-vs-flexible-vs-spacer.md dosyasına bakın.

Expanded vs Container(width: double.infinity)

Expanded Kullanımı

Row(
  children: [
    Expanded(
      child: Container(color: Colors.blue),
    ),
  ],
)
  • Row/Column içinde çalışır
  • Diğer widget'larla alan paylaşır

double.infinity Kullanımı

Container(
  width: double.infinity,
  child: Text('Tam genişlik'),
)
  • Her yerde çalışır
  • Parent'ın tüm genişliğini alır
  • Row içinde hata verebilir (unbounded width)

Birden Fazla Expanded

Row(
  children: [
    Expanded(
      flex: 1,
      child: Container(
        color: Colors.red,
        child: Center(child: Text('1')),
      ),
    ),
    Expanded(
      flex: 1,
      child: Container(
        color: Colors.green,
        child: Center(child: Text('1')),
      ),
    ),
    Expanded(
      flex: 1,
      child: Container(
        color: Colors.blue,
        child: Center(child: Text('1')),
      ),
    ),
  ],
)

Üç eşit parçaya bölünmüş ekran.

Sabit ve Expanded Karışımı

Row(
  children: [
    Container(width: 50, color: Colors.red), // Sabit
    Expanded(
      child: Container(color: Colors.blue), // Genişleyen
    ),
    Container(width: 80, color: Colors.green), // Sabit
  ],
)

Sabit genişlikler çıkarıldıktan sonra kalan alan Expanded'a verilir.

İç İçe Expanded

Expanded'ı iç içe kullanabilirsiniz:

Row(
  children: [
    Expanded(
      child: Column(
        children: [
          Expanded(
            child: Container(color: Colors.red),
          ),
          Expanded(
            child: Container(color: Colors.blue),
          ),
        ],
      ),
    ),
    Expanded(
      child: Container(color: Colors.green),
    ),
  ],
)

Hata: RenderFlex Overflow

Expanded kullanmadığınızda genellikle bu hatayla karşılaşırsınız:

Hatalı Kod

Row(
  children: [
    Container(width: 300, color: Colors.red),
    Container(width: 300, color: Colors.blue),
    Container(width: 300, color: Colors.green),
  ],
)

Toplam 900 piksel, ekran genişliğinden fazla olabilir. Overflow hatası!

Çözüm: Expanded Kullanın

Row(
  children: [
    Expanded(child: Container(color: Colors.red)),
    Expanded(child: Container(color: Colors.blue)),
    Expanded(child: Container(color: Colors.green)),
  ],
)

Her container ekranın 1/3'ünü kaplar, overflow olmaz.

Text Overflow Çözümü

Text çok uzun olduğunda taşmayı engellemek için:

Row(
  children: [
    Text('Etiket: '),
    Expanded(
      child: Text(
        'Çok uzun bir metin ki satıra sığmayabilir ama Expanded sayesinde taşmaz',
        overflow: TextOverflow.ellipsis,
      ),
    ),
  ],
)

Expanded ile ScrollView

ScrollView içinde Expanded kullanırken dikkatli olun:

Hatalı

Column(
  children: [
    Expanded(
      child: ListView(...), // Hata verebilir
    ),
  ],
)

Doğru

Column(
  children: [
    Expanded(
      child: ListView(...), // Column sabit yükseklikte olmalı
    ),
  ],
)

veya

ListView(...) // Doğrudan ListView kullanın, Expanded gerekmez

Özet

Expanded:

  • Row veya Column içinde widget'ı genişletir
  • Mevcut boş alanı doldurur
  • flex parametresi ile oransal paylaşım yapar
  • Varsayılan flex değeri 1'dir
  • İçerik için kullanılır (Spacer boşluk için)
  • Overflow hatalarını önler
  • Flexible(fit: FlexFit.tight) ile eşdeğerdir

Ne Zaman Kullanmalı:

  • Row/Column içinde esnek boyutlandırma gerektiğinde
  • Overflow hatasını önlemek için
  • Responsive düzenler oluştururken
  • Ekran boyutuna göre ölçeklendirme yapacaksanız

Kullanım Kalıpları:

  • Tek Expanded: Kalan tüm alanı kaplar
  • Çift Expanded: Alanı ikiye böler
  • Flex ile: Oransal bölüm yapar

Expanded, Flutter'da responsive ve esnek düzenler oluşturmanın temel taşlarından biridir.