Bölüm 7 — Konu 29: Navigator 2.0 (Router, RouteInformationParser, RouterDelegate)
Dizi · 29/61 Flutter Türkçe Tutorial
- Bölüm 1 — Konu 1: Flutter Nedir, Mimarisi (Widget → Element → RenderObject, Skia/Impeller)
- Bölüm 1 — Konu 2: Ortam Kurulumu (Flutter SDK, Android Studio/VS Code, Emulator/Simulator, DevTools'a İlk Bakış)
- Bölüm 1 — Konu 3: İlk Proje Yapısı (`pubspec.yaml`, `lib/`, Klasör Mimarisi, `flutter create` Anatomisi)
- Bölüm 1 — Konu 4: Hot Reload / Hot Restart Ne Yapıyor, Neden Önemli
- Bölüm 2 — Konu 5: "Her Şey Widget'tır" Felsefesi, Widget Ağacı
- Bölüm 2 — Konu 6: StatelessWidget vs StatefulWidget + `setState()` Derinlemesine (Rebuild Mekanizması)
- Bölüm 2 — Konu 7: Temel Layout — Container, Row, Column, Stack, Padding, Align, Center
- Bölüm 2 — Konu 8: Constraint Sistemi — "Constraints Go Down, Sizes Go Up, Parent Sets Position"
- Bölüm 2 — Konu 9: `Expanded`, `Flexible`, `Spacer`, Intrinsic Widget'lar
- Bölüm 3 — Konu 10: MaterialApp/CupertinoApp, Scaffold, AppBar
- Bölüm 3 — Konu 11: `ListView`, `GridView`, `SingleChildScrollView` (+ Builder Pattern)
- Bölüm 3 — Konu 12: Text, TextStyle, Icon, Image, Asset Yönetimi
- Bölüm 3 — Konu 13: Custom Widget Yazma Prensipleri (Composition Over Inheritance)
- Bölüm 3 — Konu 14: Navigator 1.0 — Push/Pop, Named Routes
- Bölüm 4 — Konu 15: Form, TextField/TextFormField, GlobalKey<FormState>, Validasyon
- Bölüm 4 — Konu 16: Theme Sistemi (ThemeData, ColorScheme)
- Bölüm 4 — Konu 17: Responsive & Adaptive Tasarım (MediaQuery, LayoutBuilder, OrientationBuilder, Breakpoint Stratejileri)
- Bölüm 5 — Konu 18: Future/Async-Await Flutter Bağlamında, FutureBuilder
- Bölüm 5 — Konu 19: `Stream`, `StreamBuilder`
- Bölüm 5 — Konu 20: HTTP İstekleri (`http` / `dio` Paketleri)
- Bölüm 5 — Konu 21: JSON Serialization (Manuel → `json_serializable`/`freezed`)
- Bölüm 5 — Konu 22: Local Storage — `shared_preferences` → `Hive` → `sqflite`/Drift
- Bölüm 6 — Konu 23: InheritedWidget ve InheritedModel — "Neden setState Yetmiyor" Sorusunun Cevabı
- Bölüm 6 — Konu 24: Provider Paketi
- Bölüm 6 — Konu 25: Riverpod (Modern Yaklaşım, Provider'ın Halefi)
- Bölüm 6 — Konu 26: BLoC/Cubit Pattern (`flutter_bloc`)
- Bölüm 6 — Konu 27: GetX (Tartışmalı Ama Yaygın)
- Bölüm 6 — Konu 28: Karşılaştırma — Hangi Projede Hangisi?
- Bölüm 7 — Konu 29: Navigator 2.0 (Router, RouteInformationParser, RouterDelegate)
- Bölüm 7 — Konu 30: `go_router` Paketi (Pratik ve Modern Çözüm)
- Bölüm 7 — Konu 31: Deep Linking
- Bölüm 7 — Konu 32: Repository Pattern, Katmanlı Mimari (Data/Domain/Presentation)
- Bölüm 7 — Konu 33: Dependency Injection (`get_it`, `injectable`)
- Bölüm 7 — Konu 34: Clean Architecture Uyarlaması, SOLID Prensipleri
- Bölüm 8 — Konu 35: Implicit Animasyonlar
- Bölüm 8 — Konu 36: Explicit Animasyonlar (`AnimationController`, `Tween`, `Curve`)
- Bölüm 8 — Konu 37: Hero Animasyonları
- Bölüm 8 — Konu 38: `CustomPainter` / `Canvas`
- Bölüm 8 — Konu 39: Rive / Lottie Entegrasyonu
- Bölüm 9 — Konu 40: Platform Channels
- Bölüm 9 — Konu 41: Permission Yönetimi (`permission_handler`)
- Bölüm 9 — Konu 42: Kamera, Konum, Sensörler
- Bölüm 9 — Konu 43: Push Notification (Firebase Cloud Messaging)
- Bölüm 9 — Konu 44: Android/iOS Build Sistemleri
- Bölüm 10 — Konu 45: Test Yazımı (Unit, Widget, Integration, Golden)
- Bölüm 10 — Konu 46: CI/CD
- Bölüm 10 — Konu 47: Rebuild Optimizasyonu (`const`, `key` Kullanımı)
- Bölüm 10 — Konu 48: DevTools Profiling
- Bölüm 10 — Konu 49: Lazy Loading, Pagination, Büyük Liste Performansı
- Bölüm 11 — Konu 50: Firebase Ekosistemi (Auth, Firestore, Storage, Functions)
- Bölüm 11 — Konu 51: Supabase Alternatifi
- Bölüm 11 — Konu 52: GraphQL (Opsiyonel)
- Bölüm 11 — Konu 53: Store Yayınlama Süreci (İmzalama, Listing, Versiyonlama)
- Bölüm 11 — Konu 54: App Size, Obfuscation, Flavor Yönetimi
- Bölüm 12 — Konu 55: Flutter Web / Desktop
- Bölüm 12 — Konu 56: Custom `RenderObject` Yazımı
- Bölüm 12 — Konu 57: Engine Mimarisi Derinlemesine (Impeller vs Skia)
- Bölüm 12 — Konu 58: Plugin Geliştirme, pub.dev'e Paket Yayınlama
- Bölüm 12 — Konu 59: Monorepo Mimarisi (Melos)
- Bölüm 12 — Konu 60: Erişilebilirlik (Accessibility) Derinlemesine
- Bölüm 12 — Konu 61: Yerelleştirme (Localization / i18n)
İçindekiler 9 başlık
- Navigator 1.0'ın Sınırlaması — Neden Navigator 2.0 Var?
- Üç Ana Bileşen
- 1. RouteInformationParser — URL'yi "Anlamlı Veriye" Çevirme
- 2. RouterDelegate — "Şu Anki Duruma Göre Hangi Ekranları Göstermeli?"
- 3. MaterialApp.router — Hepsini Birleştirme
- Neden Bu Kadar Karmaşık Görünüyor?
- Navigator 1.0 vs Navigator 2.0 — Ne Zaman Hangisi?
- 🎯 Bu Dersten Çıkarılması Gerekenler
- 📝 Ödevler
Bölüm 7'ye hoş geldin. Bu ders, Flutter'ın en karmaşık konularından birine giriyor — dürüst olmak gerekirse, bu dersten sonra öğreneceğin go_router paketi, günlük geliştirmede çok daha sık kullanacağın araç olacak. Ama Navigator 2.0'ın temel mantığını anlamak, go_router'ın neden var olduğunu ve nasıl çalıştığını kavraman için değerli.
Navigator 1.0'ın Sınırlaması — Neden Navigator 2.0 Var?
Bölüm 3 Konu 14'te öğrendiğimiz Navigator.push()/pop() (buna "Navigator 1.0" denir), zorunlu (imperative) bir yaklaşımdır — sen adım adım, "şimdi şu ekrana git" diyorsun. Bu, basit uygulamalarda gayet iyi çalışır, ama şu senaryolarda zayıf kalır:
- Web'de URL senkronizasyonu — Bir web tarayıcısında, kullanıcı geri/ileri tuşlarını kullandığında, ya da doğrudan bir URL'ye giriş yaptığında, uygulamanın doğru ekranı göstermesi gerekir. Navigator 1.0'ın "adım adım push/pop" mantığı, bunu doğal olarak desteklemez.
- Deep linking — Bir bildirime tıklandığında, uygulamayı doğrudan belirli bir ekrana (örneğin bir ürün detayına) açmak, Navigator 1.0'da karmaşık, elle yönetilen bir süreç gerektirir.
Navigator 2.0, bunun yerine bildirimsel (declarative) bir yaklaşım sunar — Dart Bölüm 13 Konu 59'da öğrendiğimiz pattern matching'in felsefesine benzer bir mantık: "şu anki durum bu, Flutter sen anla nasıl gösterileceğini."
Üç Ana Bileşen
Navigator 2.0, üç ana parçadan oluşur — bunları kavramsal olarak anlayalım (elle tam bir implementasyon yazmak, gerçekten nadiren gerekir, go_router bunu senin için yapar).
1. RouteInformationParser — URL'yi "Anlamlı Veriye" Çevirme
class UygulamaRotaAyristirici extends RouteInformationParser<UygulamaRotaKonfigurasyonu> {
@override
Future<UygulamaRotaKonfigurasyonu> parseRouteInformation(RouteInformation routeInformation) async {
final uri = routeInformation.uri;
if (uri.pathSegments.isEmpty) {
return UygulamaRotaKonfigurasyonu.anaSayfa();
}
if (uri.pathSegments[0] == 'urun') {
final id = uri.pathSegments[1];
return UygulamaRotaKonfigurasyonu.urunDetay(id);
}
return UygulamaRotaKonfigurasyonu.bilinmeyen();
}
}Bu, Dart Bölüm 7'de öğrendiğimiz extends ile Flutter'ın kendi soyut sınıfından (Bölüm 7 Konu 34'ü hatırla — soyut sınıflar bir "sözleşme" tanımlar) türetilmiş bir class. Görevi, bir URL string'ini (/urun/123 gibi), uygulamanın anlayacağı bir Dart nesnesine (UygulamaRotaKonfigurasyonu) çevirmek — tıpkı Bölüm 5 Konu 21'de öğrendiğimiz fromJson()'un, JSON'u bir Dart nesnesine çevirmesi gibi bir dönüşüm işlemi.
2. RouterDelegate — "Şu Anki Duruma Göre Hangi Ekranları Göstermeli?"
class UygulamaRouterDelegate extends RouterDelegate<UygulamaRotaKonfigurasyonu>
with ChangeNotifier { // Dart Bölüm 7'de öğrendiğimiz MIXIN, Bölüm 6'da gördüğümüz ChangeNotifier!
UygulamaRotaKonfigurasyonu _konfigurasyon = UygulamaRotaKonfigurasyonu.anaSayfa();
@override
Widget build(BuildContext context) {
return Navigator(
pages: [
MaterialPage(child: AnaEkran()),
if (_konfigurasyon.urunId != null)
MaterialPage(child: UrunDetayEkrani(id: _konfigurasyon.urunId!)),
],
onDidRemovePage: (page) {
_konfigurasyon = UygulamaRotaKonfigurasyonu.anaSayfa();
notifyListeners();
},
);
}
// ... diğer zorunlu metodlar
}Çok önemli bir gözlem: with ChangeNotifier — Bölüm 6 Konu 24'te öğrendiğimiz ChangeNotifier, burada state management dışında, navigasyon durumunu yönetmek için de kullanılıyor! Bu, Bölüm 7 Konu 36'da (Dart) öğrendiğimiz mixin'in gerçek bir Flutter kullanımı.
pages: [...] — Bu, Navigator 1.0'ın "push/pop" mantığından temel bir sapma: burada sen, "o anki state'e göre hangi sayfaların yığında (stack) olması gerektiğini" bir liste olarak bildiriyorsun — Dart Bölüm 4'te öğrendiğimiz List<Widget> (burada List<Page>) mantığı. Flutter, bu listeyi önceki listeyle karşılaştırıp (Bölüm 1 Konu 1'de öğrendiğimiz diffing mekanizmasına benzer), hangi sayfaların eklenip/çıkarılacağına kendisi karar verir.
3. MaterialApp.router — Hepsini Birleştirme
MaterialApp.router(
routerDelegate: UygulamaRouterDelegate(),
routeInformationParser: UygulamaRotaAyristirici(),
)Bölüm 3 Konu 10'da öğrendiğimiz MaterialApp(home: ...) yerine, MaterialApp.router(...) — Dart Bölüm 6 Konu 27'de öğrendiğimiz named constructor kalıbının, Flutter'ın kendi framework'ünde gerçek bir kullanımı! MaterialApp.router, MaterialApp'in navigasyonu Navigator 2.0'a devreden alternatif bir oluşturma yoludur.
Neden Bu Kadar Karmaşık Görünüyor?
Bu üç bileşeni elle yazmak, dürüst olmak gerekirse, çok fazla "boilerplate" (tekrarlayan, zorunlu) kod gerektirir — zorunlu metodları implemente etmek, state senkronizasyonunu elle yönetmek gibi. Bu tam olarak Bölüm 7 Konu 30'da öğreneceğin go_router'ın var olma sebebidir — go_router, Navigator 2.0'ın gücünü (bildirimsel navigasyon, web URL desteği, deep linking) korurken, bu karmaşıklığı büyük ölçüde gizler.
Navigator 1.0 vs Navigator 2.0 — Ne Zaman Hangisi?
Navigator 1.0 (push/pop) |
Navigator 2.0 (Router API) | |
|---|---|---|
| Öğrenme eğrisi | Düşük | Yüksek (elle yazarsan) |
| Mobil-öncelikli, basit uygulamalar | ✅ Yeterli ve pratik | Gereksiz karmaşıklık |
| Web desteği (URL senkronizasyonu) | ⚠️ Zayıf | ✅ Güçlü |
| Deep linking | ⚠️ Elle, karmaşık | ✅ Doğal destek |
| Elle yazmak pratik mi? | ✅ Evet | ❌ Genelde hayır, go_router tercih edilir |
Pratik gerçek: Bugün, Navigator 2.0'ı tamamen elle yazan geliştirici nadirdir — bunun yerine, hemen herkes go_router (veya benzer bir paket) kullanır. Bu dersin amacı, go_router'ı kullanırken "arka planda ne oluyor" sorusuna cevap verebilmen ve karşılaştığın hataları (özellikle web/deep linking ile ilgili) daha derinlemesine anlayabilmendir.
🎯 Bu Dersten Çıkarılması Gerekenler
- Navigator 1.0, zorunlu (imperative) "adım adım" navigasyon sunar; web URL senkronizasyonu ve deep linking'de zayıf kalır.
- Navigator 2.0, bildirimsel (declarative) bir yaklaşımla, "o anki state'e göre hangi sayfalar gösterilmeli" mantığıyla çalışır.
RouteInformationParser, bir URL'yi anlamlı bir Dart nesnesine çevirir;RouterDelegate, bu nesneye göre hangi sayfaların gösterileceğine karar verir veChangeNotifiermixin'ini kullanır.MaterialApp.router, bu ikisini birleştiren named constructor'dır.- Navigator 2.0'ı elle yazmak yoğun boilerplate gerektirir — pratikte neredeyse herkes
go_routergibi bir paket kullanır (bir sonraki dersimiz).
📝 Ödevler
- [ ] Kendi cümlelerinle, "Navigator 1.0'ın push/pop mantığı ile Navigator 2.0'ın bildirimsel yaklaşımı arasındaki temel felsefe farkını" açıkla.
- [ ]
RouteInformationParser'ın görevini, Dart'ta öğrendiğimizfromJson()kalıbıyla karşılaştırarak açıkla. - [ ]
RouterDelegate'in nedenChangeNotifierkullandığını, Bölüm 6'da öğrendiğin state management bilgisiyle ilişkilendir. - [ ] Basit bir
RouteInformationParsertaslağı yaz (en az 2 farklı URL yolu ayrıştıran), çalıştırmana gerek yok, sadece mantığı pratik et. - [ ] Kendi cümlelerinle, "neden pratikte çoğu geliştirici Navigator 2.0'ı elle yazmak yerine go_router kullanıyor" sorusuna cevap ver.
Sıradaki konu: Bölüm 7 — Konu 30: go_router Paketi (Pratik ve Modern Çözüm)