Flutter 3 ve Dart 3'te Gelenler: Impeller, Pattern'ler, Widget Previews, material_ui ve Sırada Ne Var
Dart 3.0 null safety'yi zorunlu yapıp record, pattern ve sealed class getirdi; 3.6–3.13 digit separator'dan primary constructor'a kadar küçük ama günlük kodu değiştiren adımlar attı. Flutter tarafında Impeller, SwiftPM, UIScene, Widget Previews ve 3.44–3.50 arasında Material'in material_ui paketine ayrılması var; dil sürümünün pubspec'ten geldiğini ve yükseltme pratiğini gerçek çıktılarla gösteriyoruz.
Sürüm notu: Bu yazıdaki örnekler Flutter 3.47.8 (Dart 3.13.7) ile denenmiştir. Flutter 3.50 (Dart 3.14) 11 Kasım 2026'da stable oldu; 3.50 ile ilgili her şey Flutter ve Dart dokümanlarından, 3.50 SDK'sı ile çalıştırılmadı. Sürüm bilgileri 15 Kasım 2026'da dart.dev'in dil evrimi sayfasından, Flutter'ın breaking changes sayfasından ve Flutter release listesinden kontrol edildi.
Önce Tahmin Et
Sitedeki serilerin ortak örnek uygulaması Bookstore'un (bir online kitapçı) Dart örneklerinde dördüncü yazıdan beri şu satır var:
class const Publisher(final String name, {final String country = 'GB'});
Aynı dosyayı, makinede kurulu SDK aynı kalmak kaydıyla, Dart 3.12 dil sürümüyle derlemeye çalışırsan ne olur? SDK 3.13.7 olduğuna göre özellik zaten içinde; derleyici bunu kabul eder mi?
Dart 3: Bir Bakışta
Dart 3.0, Mayıs 2023'te Flutter 3.10 ile geldi ve dilin en büyük değişikliğiydi: sound null safety zorunlu oldu, null safety'siz kod artık derlenmiyor. Aynı sürüm record'ları, pattern'leri, switch expression'ları ve class modifier'larını getirdi. Sonraki sürümler daha küçük ama günlük kodu değiştiren adımlar attı; dart.dev'in dil evrimi sayfasına göre:
| Dart | Tarih | Dil özelliği | Seride |
|---|---|---|---|
| 3.0 | Mayıs 2023 | record, pattern, switch expression, class modifier'ları (sealed, final, base, interface) | 03, 04, 13'teki JSON dönüşümü |
| 3.2 | Kasım 2023 | private final field'ların null kontrolünden sonra promote olması | bu yazının örneği |
| 3.3 | Şubat 2024 | extension type | Money |
| 3.6 | Aralık 2024 | digit separator (100_000) | 03 |
| 3.7 | Şubat 2025 | wildcard değişkenler (_ bağlanmaz) | 03 |
| 3.8 | Mayıs 2025 | null-aware element (?subtitle) | 03 |
| 3.10 | Kasım 2025 | dot shorthand (.paperback) | 04, Book.format |
| 3.12 | Mayıs 2026 | private named parameter (required this._remote) | 04, 14 |
| 3.13 | Ağustos 2026 | primary constructor | 04 |
| 3.14 | Kasım 2026 | yeni dil özelliği yok | - |
Ara sürümlerin (3.1, 3.4, 3.5, 3.9, 3.11) dil tarafında yeni özelliği yok; tip analizi ve araç iyileştirmeleri var. Hepsini tek dosyada, her bloğun başında hangi sürümle geldiğini yazarak dart_samples/bin/dart3_tour.dart'ta topladık. Bir parçası:
// 3.13: primary constructor; 3.12: private named parameter
class const Book(
final String title,
final Money price, {
final String? subtitle,
});
class Cart {
Cart({required this._lines});
final List<(Book, int)> _lines;
// 3.2: private final field null kontrolünden sonra promote olur
final String? _coupon = null;
String get coupon => _coupon != null ? _coupon.toUpperCase() : 'none';
dart run bin/dart3_tour.dart
3.0 3 books, placed, shipped (TR123456)
3.2 coupon: none
3.3 total 1298.00 TRY, under free shipping: false
3.7 forEach((_, _) => ...) ran 2 times
3.8 [Dune, The Hobbit, There and Back Again]
3.10 shipping 49.90 TRY
3.13 Dune 489.00, const: true
3.2 satırındaki _coupon.toUpperCase(), ! olmadan derleniyor: field private ve final olduğu için derleyici null kontrolünden sonra değerin değişemeyeceğini biliyor. 3.2'den önce bu satır için yerel bir değişkene kopyalamak gerekiyordu. 3.7 satırındaki (_, _) ise eskiden "aynı ad iki kez tanımlandı" hatasıydı.
Dil Sürümü pubspec'ten Gelir
"Önce Tahmin Et"in cevabı: hayır. Dosyanın başına // @dart=3.12 ekleyip analyze ettik:
error - zz_langver_tmp.dart:26:17 - This requires the 'primary-constructors' language feature to be enabled. Try updating your pubspec.yaml to set the minimum SDK constraint to 3.13.0 or higher, and running 'pub get'. - experiment_not_enabled
Dart'ta dil sürümü kurulu SDK'dan değil, paketin pubspec.yaml'ındaki environment: sdk: alt sınırından geliyor. sdk: ^3.13.0 yazan paket 3.13 diliyle derleniyor; ^3.8.0 yazan bir bağımlılık aynı SDK üstünde 3.8 kurallarıyla. Bu sayede eski paketler yeni SDK'da bozulmadan çalışıyor ve her paket yeni özelliklere kendi hızında geçiyor. C#'taki LangVersion'a benziyor, ama varsayılanı proje dosyasındaki SDK alt sınırı belirliyor. Pratik sonucu: yeni bir dil özelliğini kullanmak için SDK'yı güncellemek yetmez, pubspec'teki alt sınırı da yükseltmen gerekir.
Flutter 3: Rendering ve Platform Tarafı
Flutter 3.0 Mayıs 2022'de çıktı; ondan bu yana önemli değişiklikler çoğunlukla engine ve platform entegrasyonunda:
- Impeller: iOS'ta 3.10'da varsayılan oldu ve bugün iOS'taki tek rendering engine. Android'de 3.27'den beri API 29 ve üstünde, Vulkan destekleyen cihazlarda varsayılan; diğerleri eski OpenGL renderer'a düşüyor. macOS, Windows ve Linux'ta 3.47'den beri varsayılan. Web hâlâ Skia kullanıyor.
- Web'de WebAssembly:
flutter build web --wasm3.22'den beri stable. Varsayılan build hâlâ JavaScript. - Swift Package Manager: 3.44'ten beri iOS ve macOS'ta varsayılan. CocoaPods bakım modunda: SwiftPM desteklemeyen plugin varsa Flutter ona düşüyor, ama Flutter dokümanına göre CocoaPods registry'si 2 Aralık 2026'da kalıcı olarak salt okunur oluyor. Bookstore'un iOS klasöründe
Podsyok, plugin'lerFlutterGeneratedPluginSwiftPackageüzerinden geliyor. - UIScene yaşam döngüsü: Flutter dokümanına göre Xcode 27 (iOS 27 SDK) ile build edilen ve UIScene'e geçmemiş UIKit uygulamaları açılmıyor. Flutter 3.38'de desteği ekledi, 3.41'den beri yeni projelerde varsayılan ve
AppDelegate'i değiştirilmemiş projeleriflutter runya daflutter build iossırasında kendisi taşıyor. Bookstore'unInfo.plist'indeUIApplicationSceneManifestveFlutterSceneDelegatezaten var. - Widget Previews: 3.35'te deneysel olarak geldi, 3.47'de stable; ikinci yazıda
@Previewile kullandık.
Material 3 de bu dönemde varsayılan oldu: useMaterial3 3.16'dan beri true. Dokuzuncu yazıdaki ColorScheme.fromSeed teması bunun üstüne kurulu.
Material ve Cupertino'nun SDK'dan Ayrılması
Serinin en çok etkilendiği değişiklik bu, ve yazım sırasında tamamlandı. Flutter'ın geçiş rehberine göre takvim:
| Flutter | Ne oldu |
|---|---|
| 3.44 | SDK içindeki Material ve Cupertino kodu donduruldu |
| 3.47 | material_ui ve cupertino_ui 1.0 pub.dev'de, isteğe bağlı |
| 3.50 | SDK içindeki kütüphaneler resmen deprecated; kaldırma tarihi yok |
Bookstore ikinci yazıdan beri package:material_ui/material_ui.dart import ediyor; bu yüzden 3.50'deki deprecation uyarıları bizi etkilemiyor. Eski bir projede geçiş için rehberin önerdiği komut dart fix --apply --code=migrate_design_widgets; Bookstore'da kuru koşu:
dart fix --dry-run --code=migrate_design_widgets
Computing fixes in bookstore_app (dry run)...
Nothing to fix!
Rehberin iki notu daha var. GlobalMaterialLocalizations.delegates artık material_ui'den geliyor ve Cupertino ile widgets delegate'lerini de içeriyor; dokuzuncu yazıda kullandığımız tek satır bu. SDK'nın Material widget'larını kullanan bir paketle karışık çalışmak için MaterialApp.builder'a konan MaterialUiCompatibilityBridge var, ama derleme zamanındaki tip uyuşmazlıklarını çözmüyor; bağımlılıkların da geçmesini beklemek gerekiyor. go_router 18.0.0 bu yüzden material_ui'ye geçti ve en az Flutter 3.44 istiyor. go_router 18'in bir yeniliği de onEnter: her navigation'dan önce çalışan ve geçişi engelleyebilen callback. Paketin dokümanı redirect'i "legacy" diye anıyor ama desteklemeye devam ediyor; on ikinci yazıdaki auth guard'ı redirect ile bıraktık.
Flutter 3.50'de Ne Var?
3.50'nin breaking changes listesinde Material geçişinin yanında Bookstore'u ilgilendiren birkaç madde var: DropdownButtonFormField'a enabled eklenmesi ve onChanged'in isteğe bağlı olması, release modda Android engine flag'lerinin kısıtlanması, uygulamanın giriş noktaları için daha sıkı Android Intent doğrulaması ve web'de viewport-fit=cover ile SafeArea desteği. İlginç olan ilk madde: material_ui'nin değişiklik notlarına göre enabled parametresi paketin 1.8.0 sürümünde zaten geldi. Bookstore SDK'daki Material'i değil material_ui 1.11.0'ı kullandığı için bu parametre 3.47'de de elimizde; SDK 3.47'deki DropdownButtonFormField'da ise onChanged hâlâ zorunlu. Ayrılmanın pratik sonucu bu: Material'deki yenilikler artık Flutter sürümünü beklemeden paketle geliyor. Dart 3.14 yeni bir dil özelliği getirmedi. Dart 3.15 için planlananlar arasında this'in tip promotion'ı ve kontrol akışı birleşme noktalarında daha iyi promotion var; henüz yayınlanmadı.
Seriyi 3.47 hattında yazdık ve 3.50 ile çalıştırmadık. Kodun 3.50'de değişmeden derlenmesini bekliyoruz, çünkü kullandığımız tek etkilenen alan Material importları ve onlar zaten material_ui'den; ama bunu ancak 3.50 ile flutter analyze ve flutter test koşturarak doğrulayabilirsin. Yükseltme bir sonraki işin.
Yükseltme Pratiği
Flutter her çeyrekte bir stable sürüm çıkarıyor; Dart da aynı takvimle. Tek seferde büyük sıçramalar yerine her sürüme kısa sürede geçmek daha az iş. Sıra şöyle:
- Ayrı bir branch'te
flutter upgrade(ya da CI'daki sürümü değiştirmek; bizim workflow'umuzflutter-version: 3.47.8ile sabit). - Breaking changes sayfasında aradaki her sürümün listesini oku; çoğu madde seni etkilemez, etkileyenlerin geçiş rehberi var.
dart fix --dry-run, sonradart fix --apply: deprecated API'lerin önemli bir kısmı otomatik düzeltiliyor.flutter pub outdatedile paketlere bak,flutter analyzeve bütün testler.
Bookstore'da bugün flutter pub outdated'ın kısa özeti:
direct dependencies:
cupertino_icons *1.0.9 *1.0.9 2.0.0 2.0.0
9 upgradable dependencies are locked (in pubspec.lock) to older versions.
To update these dependencies, use `flutter pub upgrade`.
1 dependency is constrained to a version that is older than a resolvable version.
To update it, edit pubspec.yaml, or run `flutter pub upgrade --major-versions`.
Kilitli dokuz paket dolaylı bağımlılık (sqlite3 3.5.2 / 3.9.1 bunlardan biri); cupertino_icons'ın 2.0.0'ı ise major sürüm ve pubspec'te kısıtı değiştirmeyi gerektiriyor. Testlerin 10 saniyede koşması burada işe yarıyor: her yükseltme adımından sonra bütün uygulamayı doğrulamak bir dakikadan kısa.
Üretimde Dikkat
Store kuralları Flutter'dan hızlı değişebilir. Xcode 27 ile UIScene zorunluluğu, Play'in yıllık target API artışı ya da CocoaPods'un salt okunur olması gibi değişiklikler, uygulamanın kodu hiç değişmese bile yükseltmeyi zorunlu hale getiriyor. Bir yıl yükseltilmemiş bir uygulamada bu adımlar üst üste biniyor.
Plugin'ler en yavaş halka. Bir plugin SwiftPM'e, UIScene'e ya da material_ui'ye geçmediyse proje onu bekler. Bağımlılık seçerken pub.dev'deki son yayın tarihine ve desteklenen Flutter sürümüne bakmak, ileride yaşanacak bekleyişi azaltıyor.
SDK sürümünü sabitle. Ekipteki herkes ve CI aynı Flutter sürümünü kullanmalı; workflow'daki sabit sürüm ve pubspec.lock'un commit'lenmesi bunun için.
Sık Düşülen Tuzaklar
Birinci tuzak, SDK'yı güncelleyip pubspec'teki sdk alt sınırını bırakmak ve yeni dil özelliğinin neden çalışmadığını aramak.
İkinci tuzak, breaking changes sayfasını atlayıp yalnız derleme hatalarına bakmak. Bazı değişiklikler derlenir ama davranışı değiştirir: 3.38'deki aksiyonlu SnackBar'ın artık kendiliğinden kapanmaması gibi.
Üçüncü tuzak, deprecation uyarılarını görmezden gelmek. Kaldırma tarihi olmayan bir deprecation da bir gün kaldırmaya dönüşür ve o gün birikmiş yüzlerce uyarıyla karşılaşırsın.
Küçük Bir Deneme
★☆☆ dart_samples'ın pubspec'indeki alt sınırı ^3.10.0'a düşür ve dart analyze çalıştır. Hangi dosyalar, hangi özellikler yüzünden hata veriyor?
★★☆ Bookstore'u ayrı bir branch'te Flutter 3.50'ye yükselt: flutter analyze, flutter test ve dart fix --dry-run çıktılarını karşılaştır; golden test aynı kaldı mı?
★★★ CatalogScreen'e kategori filtresi için bir DropdownButtonFormField ekle, kategorileri GET /api/categories'ten yükle ve enabled parametresiyle yüklenirken alanı kapat. Sonra aynı widget'ı geçici olarak package:flutter/material.dart import'uyla yaz: 3.47'de hangi hatayı alıyorsun?
Bu yazıyla "Flutter ile Mobil" serisi bitiyor. Bookstore'un mobil uygulaması C# ve Angular bilgisinden yola çıkıp Dart'a, widget'lardan layout'a, resmî rehberdeki MVVM (Model-View-ViewModel; ekranı state'ten ayıran yapı) düzenine, go_router'a, ASP.NET Core API'ye, cihazda saklamaya, testlere ve mağaza sürecine kadar geldi; her yazının kodu kendi snapshot'ında duruyor. Kapsam dışında kalanlar, yani push notification, platform channel'ları, uygulama içi satın alma, analytics ve crash raporlama, ileride ayrı bir seride ele alınabilir.