Bölüm 7 — Konu 30: `go_router` Paketi (Pratik ve Modern Çözüm)
Dizi · 30/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 12 başlık
- Paketi Ekleme
- Temel Kurulum — Bildirimsel Rota Tanımlama
- Dinamik Parametreler — :id Sözdizimi
- Ekranlar Arası Geçiş — context.go() ve context.push()
- Sorgu Parametreleri (Query Parameters)
- İç İçe Rotalar (Nested Routes) — Alt Navigasyon
- Named Routes — go_router'da Daha Güvenli Bir Versiyon
- Yönlendirme (Redirect) — Giriş Kontrolü Örneği
- go_router, Bölüm 7 Konu 29'daki Karmaşıklığı Nasıl Gizliyor?
- 🎯 Bu Dersten Çıkarılması Gerekenler
- 📝 Ödevler
- 🎮 Mini Uygulama — Deep-Linkable Ürün Kataloğu
Bir önceki derste Navigator 2.0'ın ham gücünü ve karmaşıklığını gördük. go_router, bu gücü çok daha basit bir API arkasına gizleyen, Flutter ekibinin resmi olarak önerdiği bir pakettir (flutter.dev paketleri arasında "Flutter Favorite" işaretlidir).
Paketi Ekleme
flutter pub add go_routerTemel Kurulum — Bildirimsel Rota Tanımlama
import 'package:go_router/go_router.dart';
final _router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => AnaEkran(),
),
GoRoute(
path: '/urun/:id',
builder: (context, state) {
final id = state.pathParameters['id']!;
return UrunDetayEkrani(urunId: id);
},
),
],
);
void main() {
runApp(MaterialApp.router(
routerConfig: _router,
));
}Dikkat et — bu ne kadar tanıdık! routes: [...], Dart Bölüm 4'te öğrendiğimiz List yapısı; her GoRoute, Bölüm 3 Konu 14'te öğrendiğimiz Named Routes'daki Map<String, WidgetBuilder> mantığına çok benzer, ama çok daha güçlü özelliklerle (dinamik parametreler, iç içe rotalar) genişletilmiş.
builder: (context, state) => ... — Bölüm 3 Konu 11'de öğrendiğimiz builder pattern'in bir başka örneği. state, o anki rota hakkında bilgi taşır (URL parametreleri, sorgu parametreleri gibi).
Dinamik Parametreler — :id Sözdizimi
GoRoute(
path: '/urun/:id',
builder: (context, state) {
final id = state.pathParameters['id']!;
return UrunDetayEkrani(urunId: id);
},
):id, URL'nin değişken bir parçası olduğunu belirtir — /urun/123 veya /urun/abc gibi, herhangi bir değer bu yolla eşleşir. state.pathParameters['id'], Dart Bölüm 4'te öğrendiğimiz Map<String, String> erişimidir (Bölüm 3 Konu 14'te arguments'ı as String ile cast etmek zorunda kaldığımızı hatırlarsan — burada pathParameters, zaten String tipinde geliyor, bu daha temiz bir tip güvenliği).
Ekranlar Arası Geçiş — context.go() ve context.push()
ElevatedButton(
onPressed: () {
context.go('/urun/123'); // mevcut yığını DEĞİŞTİRİR
},
child: Text('Ürüne Git'),
)ElevatedButton(
onPressed: () {
context.push('/urun/123'); // yığına EKLER (Navigator.push'a benzer)
},
child: Text('Ürüne Git'),
)go() ile push() arasındaki fark: go(), Bölüm 3 Konu 14'te öğrendiğimiz stack (yığın) kavramını hatırlarsan, mevcut yığını tamamen yeni bir rotayla değiştirir (web'de "adres çubuğuna URL yazmak" gibi düşün). push(), geleneksel Navigator 1.0'ın push'una daha yakın davranır — yığına ekler, geri tuşuyla önceki ekrana dönülebilir.
Sorgu Parametreleri (Query Parameters)
context.go('/arama?q=laptop&kategori=elektronik');GoRoute(
path: '/arama',
builder: (context, state) {
final sorgu = state.uri.queryParameters['q'];
final kategori = state.uri.queryParameters['kategori'];
return AramaSonuclari(sorgu: sorgu, kategori: kategori);
},
)state.uri.queryParameters, yine Map<String, String> — web tarayıcılarında gördüğün ?q=laptop&kategori=elektronik tarzı URL'lerin doğal Flutter karşılığı.
İç İçe Rotalar (Nested Routes) — Alt Navigasyon
GoRoute(
path: '/urunler',
builder: (context, state) => UrunlerEkrani(),
routes: [ // İÇ İÇE rotalar
GoRoute(
path: ':id', // tam yolu: /urunler/:id
builder: (context, state) {
final id = state.pathParameters['id']!;
return UrunDetayEkrani(urunId: id);
},
),
],
)Bu, Dart Bölüm 4'te öğrendiğimiz iç içe koleksiyon yapılarına benzer bir hiyerarşi — routes: içinde başka routes: tanımlayarak, URL yapısını ağaç şeklinde organize edebilirsin (/urunler/:id, /urunler/:id/yorumlar gibi).
Named Routes — go_router'da Daha Güvenli Bir Versiyon
GoRoute(
path: '/urun/:id',
name: 'urun-detay', // bir İSİM veriyoruz
builder: (context, state) => UrunDetayEkrani(urunId: state.pathParameters['id']!),
)context.goNamed('urun-detay', pathParameters: {'id': '123'});Bu, Bölüm 3 Konu 14'te öğrendiğimiz Named Routes'un go_router versiyonudur — URL string'ini elle yazmak yerine (yazım hatası riski), isimle ve tip güvenli parametrelerle rotaya gidiyorsun.
Yönlendirme (Redirect) — Giriş Kontrolü Örneği
final _router = GoRouter(
redirect: (context, state) {
final girisYapildiMi = false; // gerçek uygulamada bir state'ten gelir (Bölüm 6'yı hatırla)
final girisSayfasindaMi = state.matchedLocation == '/giris';
if (!girisYapildiMi && !girisSayfasindaMi) {
return '/giris'; // giriş yapılmamışsa, giriş ekranına yönlendir
}
return null; // null = yönlendirme yok, olduğu gibi devam
},
routes: [...],
);redirect, Dart Bölüm 5'te öğrendiğimiz anonim fonksiyondur — her navigasyon denemesinde çalışır ve null (yönlendirme yok) veya bir String (yeni hedef yol) döndürür. Bu, gerçek uygulamalarda "giriş yapılmadan belirli ekranlara erişilemez" gibi kuralları merkezi bir yerde uygulamanın standart yoludur.
go_router, Bölüm 7 Konu 29'daki Karmaşıklığı Nasıl Gizliyor?
go_router, arka planda tam olarak bir önceki derste öğrendiğimiz RouteInformationParser ve RouterDelegate'i kendi içinde implemente eder — sen bunları görmüyorsun bile, sadece GoRoute listesi tanımlıyorsun. Bu, Bölüm 5 Konu 20'de dio'nun http'nin üzerine, veya Bölüm 6 Konu 24'te Provider'ın InheritedWidget'ın üzerine inşa edilmesiyle aynı mühendislik deseni — karmaşık, güçlü bir temeli, basit bir arayüz arkasında sunmak.
🎯 Bu Dersten Çıkarılması Gerekenler
go_router, Navigator 2.0'ın gücünü,GoRoutelistesi ile bildirimsel ve basit bir API arkasında sunar.:parametresözdizimi, dinamik URL parçalarını yakalar;state.pathParameters/state.uri.queryParameters, tip güvenli erişim sağlar.context.go(), yığını değiştirir;context.push(), yığına ekler (Navigator 1.0'a benzer).- İç içe
routes:, URL yapısını ağaç şeklinde organize etmeyi sağlar. redirect, merkezi navigasyon kurallarını (örn. giriş kontrolü) uygulamanın standart yoludur.
📝 Ödevler
- [ ]
go_routerile en az 3 route'lu (ana sayfa, liste, detay) bir navigasyon yapısı kur. - [ ] Dinamik bir parametre (
:id) içeren bir route yaz,context.go()ile farklı ID'lerle test et. - [ ] Bir arama ekranı için sorgu parametreleri (
?q=...) kullan,state.uri.queryParametersile oku. - [ ] İç içe route'lar (nested routes) kullanarak, en az 2 seviyeli bir URL yapısı (
/urunler/:id) kur. - [ ]
redirectkullanarak basit bir "giriş yapılmadan erişilemez" kontrolü ekle (sabit birbooldeğişkenle test edebilirsin).
🎮 Mini Uygulama — Deep-Linkable Ürün Kataloğu
Bölüm 7'de öğrendiğin navigasyon bilgisini pekiştiren bir mini proje:
Gereksinimler:
go_routerile en az 4 route: ana sayfa, ürün listesi, ürün detayı (:idile), ve bir "hakkında" sayfası.- Ürün listesinden bir ürüne tıklandığında,
context.go()ile detay sayfasına geç. - Detay sayfasında bir "geri" butonu ile ana listeye dön.
- Bir arama kutusu ekle,
context.go('/urunler?q=...')ile sorgu parametresiyle listeyi filtrele (gerçek filtreleme mantığı basit olabilir — örn. sadece parametreyi ekranda gösterebilirsin). - Bonus:
redirectile, sahte bir "bakım modu" bayrağıtrueolduğunda tüm rotaları bir "bakımdayız" ekranına yönlendir.
Sıradaki konu: Bölüm 7 — Konu 31: Deep Linking