Bölüm 8 — Konu 39: Rive / Lottie Entegrasyonu
Dizi · 39/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
- Neden Hazır Animasyon Dosyaları?
- Lottie — After Effects Animasyonlarını Oynatma
- LottieBuilder + Kontrol — Konu 36'daki AnimationController ile Birleşim
- Rive — Etkileşimli, Durum Tabanlı Animasyonlar
- Lottie mi, Rive mı?
- Bölüm 8'i Kapatırken — Hangi Aracı Ne Zaman Kullanırsın?
- 🎯 Bu Dersten Çıkarılması Gerekenler
- 📝 Ödevler
- 🎮 Mini Uygulama — Bölüm 8 Checkpoint: Animasyonlu Ürün Vitrini
Bölüm 8'in son konusuna geldik. Konu 35-38'de Flutter'ın kendi animasyon araçlarını (implicit, explicit, Hero, Canvas) öğrendik — bu son derste, tasarımcılar tarafından ayrı bir araçla üretilip Flutter'a hazır dosya olarak aktarılan animasyonları nasıl kullanacağını göreceğiz.
Neden Hazır Animasyon Dosyaları?
Konu 38'de CustomPainter ile elle bir şekil çizmenin ne kadar ayrıntılı olduğunu gördün. Şimdi düşün: bir maskot karakterin zıplayarak selam vermesi, karmaşık bir yüklenme animasyonu, ya da bir onay işaretinin çiziliyormuş gibi belirmesi gibi tasarımcı-üretimi animasyonları Canvas ile elle kodlamak günler sürer. Bunun yerine, tasarımcılar bu animasyonları özel araçlarla (Adobe After Effects, Rive Editor) hazırlar, bir dosya olarak dışa aktarır, sen de bu dosyayı Flutter'da birkaç satır kodla oynatırsın.
İki popüler format var: Lottie (After Effects animasyonlarını JSON'a çeviren, Airbnb'nin açık kaynak formatı) ve Rive (kendi editörüyle gelen, etkileşimli animasyonlara daha uygun daha yeni bir format).
Lottie — After Effects Animasyonlarını Oynatma
flutter pub add lottieimport 'package:lottie/lottie.dart';
Lottie.asset('assets/animasyonlar/yukleniyor.json')Bu kadar basit — assets/ klasörüne (Bölüm 3 Konu 12'de öğrendiğimiz asset yönetimini hatırla) bir .json animasyon dosyası koyup pubspec.yaml'da tanımladıktan sonra, Lottie.asset(...), animasyonu otomatik olarak oynatmaya başlar (varsayılan olarak bir kere oynar).
Lottie.asset(
'assets/animasyonlar/yukleniyor.json',
repeat: true, // sürekli tekrar oynat
animate: true, // otomatik başlasın
width: 200,
height: 200,
fit: BoxFit.contain, // Bölüm 3 Konu 12'deki BoxFit kavramını hatırla
)Ağdan da yükleyebilirsin:
Lottie.network('https://ornek.com/animasyon.json')Bölüm 3 Konu 12'de Image.asset ile Image.network arasındaki paralel isimlendirmeyi hatırlarsan — Lottie.asset/Lottie.network, aynı tasarım kalıbını takip ediyor.
LottieBuilder + Kontrol — Konu 36'daki AnimationController ile Birleşim
Lottie animasyonunu, Konu 36'da öğrendiğimiz AnimationController ile elle kontrol edebilirsin — örneğin bir "beğen" butonuna basıldığında animasyonu bir kere oynatmak istiyorsan:
class BegenButonu extends StatefulWidget {
const BegenButonu({super.key});
@override
State<BegenButonu> createState() => _BegenButonuState();
}
class _BegenButonuState extends State<BegenButonu> with SingleTickerProviderStateMixin {
late final AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this); // duration, Lottie dosyasından otomatik alınır
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => _controller.forward(from: 0), // baştan bir kere oynat
child: Lottie.asset(
'assets/animasyonlar/kalp.json',
controller: _controller,
onLoaded: (composition) {
_controller.duration = composition.duration; // animasyonun gerçek süresini al
},
),
);
}
}Dikkat et: AnimationController'ı burada kendi duration'ını elle belirtmeden oluşturduk — onLoaded callback'i, Lottie dosyası yüklendiğinde çağrılır ve dosyanın kendi doğal süresini (composition.duration) sana verir; bunu _controller.duration'a atayarak, kontrolcünün animasyon dosyasıyla tam senkronize çalışmasını sağlıyoruz.
Rive — Etkileşimli, Durum Tabanlı Animasyonlar
flutter pub add riveimport 'package:rive/rive.dart';
RiveAnimation.asset('assets/animasyonlar/karakter.riv')Rive'ın Lottie'den temel farkı: Rive dosyaları, kendi içinde bir State Machine (durum makinesi) taşıyabilir — yani animasyon, tek bir doğrusal oynatım değil, girdilere göre farklı davranan bir sistem olabilir (örneğin bir karakterin "bekleme", "yürüme", "zıplama" durumları arasında, senin kontrolünle geçiş yapması).
class EtkilesimliKarakter extends StatefulWidget {
const EtkilesimliKarakter({super.key});
@override
State<EtkilesimliKarakter> createState() => _EtkilesimliKarakterState();
}
class _EtkilesimliKarakterState extends State<EtkilesimliKarakter> {
StateMachineController? _controller;
SMIBool? _tiklandiGirdisi; // State Machine'e bağlı bir boolean girdi
void _onRiveInit(Artboard artboard) {
final controller = StateMachineController.fromArtboard(artboard, 'Durum Makinesi');
if (controller != null) {
artboard.addController(controller);
_controller = controller;
_tiklandiGirdisi = controller.findInput<bool>('tiklandi') as SMIBool?;
}
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
_tiklandiGirdisi?.value = true; // Rive editöründe tanımlı animasyonu tetikle
},
child: RiveAnimation.asset(
'assets/animasyonlar/karakter.riv',
onInit: _onRiveInit,
),
);
}
}Buradaki SMIBool (State Machine Input — Boolean), Dart Bölüm 9'da öğrendiğimiz tip sistemine bir örnek: Rive, State Machine'e bool, double, "trigger" gibi farklı girdi tipleri tanımlamana izin verir; findInput<bool>('tiklandi'), generic bir arama yapıp, Rive editöründe tasarımcının tanımladığı tiklandi adlı girdiye koddan erişim sağlıyor.
Pratik gerçek: Rive dosyalarını kendin tasarlamazsın (Rive Editor ayrı bir araçtır) — genelde bir tasarımcıdan .riv dosyasını State Machine girdi isimleriyle birlikte alırsın (örn. "bu girdinin adı tiklandi, bool tipinde") ve koddan bu isimlere göre bağlarsın.
Lottie mi, Rive mı?
| Lottie | Rive | |
|---|---|---|
| Kaynak araç | Adobe After Effects (Bodymovin eklentisi) | Rive'ın kendi editörü |
| Dosya formatı | .json |
.riv |
| Etkileşim/durum makinesi | ❌ Yok (doğrusal oynatım) | ✅ Var (State Machine) |
| Ekosistem/örnek bolluğu | Çok yaygın, geniş hazır kütüphane (LottieFiles.com) | Daha yeni, büyüyen bir topluluk |
| Ne zaman tercih edilir | Basit, tek seferlik animasyonlar (yükleniyor, onay işareti, splash) | Karaktere/duruma göre değişen, etkileşimli animasyonlar (oyun benzeri UI, maskotlar) |
Bölüm 8'i Kapatırken — Hangi Aracı Ne Zaman Kullanırsın?
Basit bir değer değişimi (boyut, renk, opaklık) → Implicit animasyon (Konu 35)
İnce kontrol, birden fazla bağlı animasyon → Explicit animasyon (Konu 36)
İki ekran arasında ortak bir görselin geçişi → Hero (Konu 37)
Veriye dayalı özel bir şekil/grafik → CustomPainter (Konu 38)
Tasarımcı tarafından hazırlanmış karmaşık animasyon → Lottie / Rive (Konu 39)Gerçek bir uygulamada, bu beş aracın hepsini bir arada kullanman gayet normaldir — örneğin bir splash screen'de Rive, kartlar arası geçişte Hero, bir yükleme göstergesinde CustomPainter, ve butonlarda implicit animasyonlar.
🎯 Bu Dersten Çıkarılması Gerekenler
- Lottie, After Effects kökenli
.jsonanimasyonlarını oynatır —Lottie.asset/Lottie.network,Image.asset/Image.networkile aynı tasarım kalıbını takip eder. - Lottie animasyonları, Konu 36'daki
AnimationControllerile elle kontrol edilebilir;onLoadedcallback'i, dosyanın gerçek süresini vermeni sağlar. - Rive,
.rivdosyaları ve State Machine ile, girdilere göre davranışı değişen etkileşimli animasyonlar sunar — Lottie'nin sunmadığı bir özellik. - Rive'da
StateMachineController+findInput<T>(), koddan tasarımcının tanımladığı girdilere (bool/double/trigger) bağlanmanı sağlar. - Basit, tek seferlik animasyonlarda Lottie; etkileşimli/durum tabanlı animasyonlarda Rive tercih edilir.
- Bölüm 8'de öğrendiğin beş araç (implicit, explicit, Hero, CustomPainter, Lottie/Rive), gerçek bir uygulamada genelde bir arada kullanılır.
📝 Ödevler
- [ ] LottieFiles.com'dan ücretsiz bir animasyon (örn. bir "yükleniyor" animasyonu) indir,
Lottie.assetile bir splash screen'de göster. - [ ] İndirdiğin bir Lottie animasyonunu,
AnimationControllerile bir butona basıldığında bir kere oynatacak şekilde bağla (onLoadedile süresini al). - [ ] Rive'ın örnek dosyalarından (rive.app üzerindeki topluluk dosyaları) birini indir,
RiveAnimation.assetile ekranda göster. - [ ] Kendi cümlelerinle, "Lottie ile Rive arasındaki temel farkın, State Machine kavramıyla nasıl ilişkili olduğunu" açıkla.
🎮 Mini Uygulama — Bölüm 8 Checkpoint: Animasyonlu Ürün Vitrini
Bölüm 8'in tamamını (implicit, explicit, Hero, CustomPainter, Lottie/Rive) bir araya getiren bir mini proje:
Gereksinimler:
- Splash screen: Uygulama açılışında 1-2 saniye gösterilen, bir Lottie animasyonu içeren bir ekran (
Future.delayedile Bölüm 5 Konu 18'i hatırlayarak, sonra ana ekrana geç). - Ürün listesi:
ListView.builderile bir ürün listesi; her ürün kartı, dokunulduğundaAnimatedContainer(Konu 35) ile hafifçe büyüsün (basılı tutma efekti —GestureDetector'ınonTapDown/onTapUpile). - Ürün detay geçişi: Listedeki ürün resminden detay ekranına
Hero(Konu 37) ile geçiş. - Yüklenme göstergesi: Detay ekranında, sahte bir yükleme süresi boyunca
CustomPainter(Konu 38) ile çizilmiş dairesel bir ilerleme göstergesi. - Bonus: "Sepete Ekle" butonuna basıldığında,
AnimationController(Konu 36) ile bir "başarı" ikonu (veya bir Lottie onay animasyonu) kısaca belirip kaybolsun.
Sıradaki konu: Bölüm 9 — Konu 40: Platform Channels (Native Android/iOS Koduyla Konuşma)