Flutter Nedir? Kapsamlı Başlangıç Rehberi

12 dakika okuma9 Şubat 2026Güncellendi: 9 Mar 2026
Flutter nedirFlutter ne için kullanılırWhat is FlutterFlutter tutorialFlutter başlangıçFlutter öğrenFlutter mobile developmentCross-platform developmentDart programlamaFlutter vs native

# Flutter Nedir? Yeni Başlayanlar İçin Kapsamlı Rehber

Flutter, Google tarafından geliştirilen açık kaynaklı bir UI framework'üdür. Tek bir kod tabanı ile iOS, Android, Web, Windows, macOS ve Linux platformlarında yüksek performanslı, görsel açıdan zengin uygulamalar geliştirmenize olanak tanır. 2018'de kararlı sürümüne ulaşmasından bu yana hızla büyüyen Flutter, bugün dünya genelinde milyonlarca geliştirici tarafından kullanılıyor.

Bu rehberde Flutter'ın ne olduğunu, nasıl çalıştığını, ne zaman tercih edilmesi gerektiğini ve başlarken yapılan yaygın hataları ele alacağız.

Flutter Nasıl Çalışır?

Flutter'ın diğer cross-platform çözümlerden temel farkı, kendi render motoruna sahip olmasıdır. React Native gibi framework'ler platforma özgü UI bileşenlerini bir köprü üzerinden çağırırken, Flutter Skia (ve artık Impeller) grafik motoru aracılığıyla her pikseli doğrudan kendisi çizer. Bu yaklaşımın sonuçları şunlardır:

  • Her platformda piksel düzeyinde aynı görünüm
  • Platforma bağımlılık olmadan tutarlı 60/120 FPS performans
  • UI davranışlarında platform farklılıklarından kaynaklanan sürprizlerin olmaması
  • Neden Flutter Tercih Edilmeli?

    1. Hot Reload ile Hızlı Geliştirme

    Hot Reload, Flutter'ın en çok sevilen özelliklerinden biridir. Kodunuzda bir değişiklik yaptığınızda uygulamanın durumu korunarak UI anında güncellenir. Deneyimlerime göre bu özellik, özellikle UI ince ayarlarında geliştirme süresini yarıya kadar düşürebiliyor.

    2. Widget Tabanlı Mimari

    Flutter'da ekranda gördüğünüz her şey bir widget'tır: bir buton, bir metin, bir padding, hatta uygulamanın kendisi. Widget'lar birbirinin içine yerleştirilerek (composition) karmaşık arayüzler oluşturulur.

    dart
    import class="code-string">'package:flutter/material.dart';
    
    class KarsilamaKarti extends StatelessWidget {
      final String kullaniciAdi;
    
      const KarsilamaKarti({super.key, required this.kullaniciAdi});
    
      @override
      Widget build(BuildContext context) {
        return Card(
          elevation: class="code-number">4,
          margin: const EdgeInsets.all(class="code-number">16),
          child: Padding(
            padding: const EdgeInsets.all(class="code-number">24),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const Icon(Icons.waving_hand, size: class="code-number">48, color: Colors.amber),
                const SizedBox(height: class="code-number">12),
                Text(
                  class="code-string">'Hoş geldin, $kullaniciAdi!',
                  style: Theme.of(context).textTheme.headlineSmall,
                ),
                const SizedBox(height: class="code-number">8),
                Text(
                  class="code-string">'Bugün nasıl yardımcı olabilirim?',
                  style: Theme.of(context).textTheme.bodyMedium,
                ),
              ],
            ),
          ),
        );
      }
    }

    Bu örnekte `Card`, `Padding`, `Column`, `Icon`, `Text` gibi widget'lar bir araya gelerek tek bir bileşen oluşturuyor. Etkili bulduğum bir yaklaşım: her ekranı küçük, tek sorumluluğu olan widget'lara bölmek. Bu hem okunabilirliği artırıyor hem de rebuild performansını iyileştiriyor.

    3. Durum Yönetimi (State Management)

    Flutter'da widget'lar StatelessWidget ve StatefulWidget olmak üzere ikiye ayrılır. StatefulWidget, kendi iç durumunu yönetebilen widget'lardır:

    dart
    class SayacSayfasi extends StatefulWidget {
      const SayacSayfasi({super.key});
    
      @override
      State<SayacSayfasi> createState() => _SayacSayfasiState();
    }
    
    class _SayacSayfasiState extends State<SayacSayfasi> {
      int _sayac = class="code-number">0;
    
      void _artir() {
        setState(() {
          _sayac++;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text(class="code-string">'Sayac')),
          body: Center(
            child: Text(
              class="code-string">'Tıklama: $_sayac',
              style: const TextStyle(fontSize: class="code-number">32),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _artir,
            child: const Icon(Icons.add),
          ),
        );
      }
    }

    Daha büyük projelerde `setState` yetmez. Bu noktada Riverpod, Bloc veya Provider gibi durum yönetim çözümlerine geçmek gerekir. Deneyimlerime göre küçük-orta ölçekli projelerde Riverpod hem öğrenmesi kolay hem de ölçeklenebilir bir seçenek.

    4. Dart Dili

    Flutter, Dart dilini kullanır. Dart'ı özel kılan özellikler:

  • **Null safety**: Derleme zamanında null hatalarını yakalar
  • **Async/await**: Asenkron işlemleri senkron gibi yazmanızı sağlar
  • **JIT ve AOT derleme**: Geliştirme sırasında JIT (hızlı yeniden yükleme), üretimde AOT (yüksek performans)
  • **Pattern matching**: Dart 3 ile gelen güçlü desen eşleştirme
  • dart
    class=class="code-string">"code-comment">// Dartclass="code-string">'ta asenkron bir API çağrısı örneği
    Future<List<Urun>> urunleriGetir() async {
      try {
        final yanit = await http.get(Uri.parse('https:class=class="code-string">"code-comment">//api.ornek.com/urunlerclass="code-string">'));
    
        if (yanit.statusCode == class="code-number">200) {
          final List<dynamic> veri = jsonDecode(yanit.body);
          return veri.map((json) => Urun.fromJson(json)).toList();
        } else {
          throw Exception('Ürünler yüklenemedi: ${yanit.statusCode}class="code-string">');
        }
      } catch (e) {
        throw Exception('Ağ hatası: $e');
      }
    }

    5. Zengin Ekosistem

    pub.dev üzerinde 40.000'den fazla paket bulunuyor. Sık kullanılan paketlerden bazıları:

  • **dio** — gelişmiş HTTP istemcisi
  • **go_router** — deklaratif yönlendirme
  • **flutter_bloc / riverpod** — durum yönetimi
  • **hive / drift** — yerel veritabanı
  • **freezed** — değişmez (immutable) veri modelleri
  • Flutter ile Ne Geliştirebilirsiniz?

  • **E-ticaret uygulamaları** — ödeme, sepet, ürün kataloğu
  • **Fintech ürünleri** — banka uygulamaları, kripto cüzdanları
  • **Kurumsal iç sistem araçları** — envanter, CRM, görev yönetimi
  • **Sağlık uygulamaları** — randevu takip, hasta portalı
  • **Eğitim platformları** — interaktif ders içerikleri
  • **MVP ve prototipler** — hızlı pazar doğrulaması gereken projeler
  • **IoT kontrol panelleri** — cihaz yönetim arayüzleri
  • Flutter Ne Zaman Kullanılmalı?

    Flutter şu durumlarda güçlü bir tercih olur:

  • **Birden fazla platforma** aynı anda çıkmak istiyorsanız
  • **Özelleştirilmiş, marka odaklı bir UI** tasarımınız varsa
  • **Hızlı iterasyon** ve sık sürüm çıkmak öncelikliyse
  • **Takımınız küçükse** ve her platforma ayrı geliştirici ayıramıyorsanız
  • **Performansın kritik olduğu** animasyonlu arayüzler yapıyorsanız
  • Flutter Ne Zaman Kullanılmamalı?

    Her araç gibi Flutter da her senaryoya uygun değildir:

  • **Platforma özgü derin entegrasyon** gerekiyorsa (örneğin karmaşık Bluetooth veya AR/VR senaryoları) — native geliştirme daha uygun olabilir
  • **Mevcut bir native uygulamaya küçük bir modül ekliyorsanız** — Flutter'ı embed etmek karmaşıklık artırabilir
  • **3D oyun geliştirme** yapıyorsanız — Unity veya Unreal daha iyi seçenekler
  • **Tarayıcı SEO performansı birincil öncelikse** — Flutter web, geleneksel HTML/JS çözümlerine göre SEO açısından hâlâ geride
  • **Takımınız tamamen native deneyime sahipse** ve cross-platform ihtiyacı yoksa — geçiş maliyeti gereksiz olabilir
  • Avantajlar ve Dezavantajlar

    | Avantajlar | Dezavantajlar |

    |---|---|

    | Tek kod tabanı, 6 platform | Uygulama boyutu native'e göre daha büyük (~15-20 MB başlangıç) |

    | Hot Reload ile hızlı geliştirme | Platforma özgü API'lere erişim için eklenti gerekebilir |

    | Zengin widget kütüphanesi | Web desteği henüz native JS kadar olgun değil |

    | Güçlü topluluk ve Google desteği | Dart, JavaScript/Kotlin kadar yaygın değil |

    | Tutarlı 60/120 FPS performans | Büyük uygulamalarda derleme süreleri uzayabilir |

    | Kapsamlı test altyapısı | Native görünüm isteyenler için Cupertino/Material arasında seçim gerekir |

    Yeni Başlayanların Yaptığı Yaygın Hatalar

    1. Her Şeyi Tek Widget'ta Yazmak

    Yeni başlayanlar genelde tüm ekranı tek bir `build` metoduna sığdırmaya çalışır. Bu, hem okunması zor hem de performans açısından sorunlu bir yaklaşımdır.

    dart
    class=class="code-string">"code-comment">// Kötü: Her şey tek yerde
    class AnaSayfa extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: [
              class=class="code-string">"code-comment">// class="code-number">200 satır iç içe widget...
            ],
          ),
        );
      }
    }
    
    class=class="code-string">"code-comment">// İyi: Parçalara ayrılmış
    class AnaSayfa extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: [
              const UstBaslik(),
              const KategoriListesi(),
              const OneCikanUrunler(),
            ],
          ),
        );
      }
    }

    2. setState'i Gereğinden Fazla Kullanmak

    Küçük örneklerde `setState` sorunsuz çalışır. Ama uygulama büyüdüğünde her yerde `setState` kullanmak, gereksiz rebuild'lere ve karmaşık koda yol açar. Erken aşamada bir durum yönetim çözümü seçmek uzun vadede zaman kazandırır.

    3. BuildContext'i Yanlış Kullanmak

    `BuildContext`, widget ağacındaki konumu temsil eder. Yanlış context ile `Navigator.of(context)` veya `Theme.of(context)` çağırmak zor bulunan hatalara neden olur. Özellikle dialog ve bottom sheet açarken dikkatli olunmalıdır.

    4. Platform Farklılıklarını Göz Ardı Etmek

    Flutter piksel düzeyinde tutarlılık sağlasa da, kullanıcı deneyimi beklentileri platformdan platforma değişir. iOS kullanıcıları geri kaydırma hareketi beklerken, Android kullanıcıları geri tuşunu kullanır. Etkili bulduğum bir yaklaşım: Material ve Cupertino widget'larını platforma göre koşullu kullanmak.

    5. Test Yazmayı Ertelemek

    Flutter, unit test, widget test ve entegrasyon testi için yerleşik destek sunar. Baştan test yazmak yerine sonraya bırakmak, projenin büyüdükçe kırılgan hale gelmesine yol açar.

    dart
    class=class="code-string">"code-comment">// Basit bir widget testi örneği
    testWidgets(class="code-string">'Sayac artırma testi', (WidgetTester tester) async {
      await tester.pumpWidget(const MaterialApp(home: SayacSayfasi()));
    
      class=class="code-string">"code-comment">// Başlangıç değerini kontrol et
      expect(find.text(class="code-string">'Tıklama: class="code-number">0'), findsOneWidget);
    
      class=class="code-string">"code-comment">// Butona tıkla
      await tester.tap(find.byIcon(Icons.add));
      await tester.pump();
    
      class=class="code-string">"code-comment">// Değerin arttığını doğrula
      expect(find.text(class="code-string">'Tıklama: class="code-number">1'), findsOneWidget);
    });

    Başlamak İçin Adım Adım Yol Haritası

    1. Ortamı Kurun

    Flutter SDK'yı [flutter.dev](https://flutter.dev) üzerinden indirip kurun. Ardından terminalde şu komutu çalıştırarak kurulumun doğru yapıldığını kontrol edin:

    dart
    class=class="code-string">"code-comment">// Terminal komutu:
    class=class="code-string">"code-comment">// flutter doctor

    Bu komut eksik bağımlılıkları ve yapılandırma sorunlarını size gösterecektir.

    2. Dart Temellerini Öğrenin

    Flutter'a geçmeden önce Dart'ın temellerine hakim olun: değişkenler, fonksiyonlar, sınıflar, null safety, async/await. [dart.dev](https://dart.dev) üzerindeki dil turu bunun için ideal bir başlangıç noktasıdır.

    3. Widget Kataloğunu İnceleyin

    Flutter'ın resmi widget kataloğunu inceleyin. `Container`, `Row`, `Column`, `Stack`, `ListView` ve `GridView` gibi temel layout widget'larını öğrenmek, ihtiyaç duyacağınız her arayüzü inşa etmenize olanak tanır.

    4. Gerçek Bir Proje Yapın

    Eğitim videolarını sonsuz döngüde izlemek yerine, küçük ama gerçek bir proje yapın. Yapılacaklar listesi, hava durumu uygulaması veya basit bir not defteri gibi projeler başlangıç için idealdir.

    5. Durum Yönetimini Öğrenin

    İlk projenizde `setState` yeterli olacaktır. İkinci projede Riverpod veya Bloc gibi bir çözüme geçin. Deneyimlerime göre durum yönetimini erken öğrenmek, ileride büyük refactoring ihtiyacını ortadan kaldırır.

    6. Paket Ekosistemini Tanıyın

    pub.dev üzerindeki popüler paketlere göz atın. Ancak her işlev için bir paket eklemek yerine, gerçekten ihtiyaç duyduğunuz paketleri seçin. Gereksiz bağımlılıklar projenin bakımını zorlaştırır.

    Sonuç

    Flutter, modern uygulama geliştirmede hız, kalite ve ölçeklenebilirlik arasında güçlü bir denge sunar. Tek kod tabanı ile birden fazla platforma ulaşmak, küçük ekipler için büyük bir avantajdır. Ancak her teknoloji gibi Flutter da doğru senaryoda kullanıldığında en iyi sonuçları verir.

    Önemli olan, temellerle başlamak, küçük projelerle pratik yapmak ve ihtiyaç duydukça daha gelişmiş konulara geçmektir. Flutter topluluğu son derece aktif ve yardımsever; yolunuzda takıldığınızda Stack Overflow, Flutter Discord veya r/FlutterDev gibi kaynaklara her zaman başvurabilirsiniz.

    Flutter projeniz için teknik yol haritası oluşturmak isterseniz iletişime geçebilirsiniz.

    İlgili Makaleler

    Flutter Projeniz mi Var?

    iOS, Android ve web için yüksek performanslı Flutter uygulamaları geliştiriyorum.

    İletişime Geç