Gereksinimler ve Ön Hazırlık
Dinamik bir liste yapısı kurmadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. Flutter SDK'nın 3.20 ve üzeri sürümleri, performans iyileştirmeleri ve modern widget desteği açısından önerilir.
- Flutter SDK: En son kararlı (stable) sürüm.
- IDE: VS Code veya Android Studio (Flutter ve Dart eklentileri kurulu).
- Temel Bilgi: Stateless ve Stateful Widget kavramlarına hakimiyet.
Projenizi oluşturmak için terminalinizde flutter create dinamik_liste_app komutunu çalıştırarak işe başlayabilirsiniz. Ardından main.dart dosyasını temizleyerek temel bir yapı kuracağız.
Temel Liste Yapısı: ListView.builder Kullanımı
Flutter'da dinamik listeler için en verimli yöntem ListView.builder kullanmaktır. Bu yöntem, sadece ekranda görünen (render edilen) elemanları oluşturur, bu da uzun listelerde bellek yönetimi (memory management) açısından kritiktir.
// Basit bir dinamik liste örneği
ListView.builder(
itemCount: 50,
itemBuilder: (context, index) {
return ListTile(
title: Text('Eleman Numarası: $index'),
);
},
)
Yukarıdaki kod, 50 elemanlı bir listeyi belleği yormadan ekrana çizer. itemCount listenin uzunluğunu belirtirken, itemBuilder her bir satırın nasıl görüneceğini tanımlar.
Veri Modeli ile Dinamik Liste Oluşturma
Profesyonel uygulamalarda veriler genellikle bir API'den veya yerel bir veritabanından nesne (object) olarak gelir. İlk adım olarak verimizi temsil edecek bir sınıf oluşturmalıyız.
class Kullanici {
final String isim;
final String gorev;
Kullanici(this.isim, this.gorev);
}
final List kullanicilar = [
Kullanici("Ahmet Yılmaz", "Yazılım Geliştirici"),
Kullanici("Ayşe Demir", "Tasarımcı"),
];
Bu sınıf yapısı, verilerinizin tip güvenliğini (type-safety) sağlar. Şimdi bu listeyi ListView.builder içinde kullanalım.
ListView.builder(
itemCount: kullanicilar.length,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.person),
title: Text(kullanicilar[index].isim),
subtitle: Text(kullanicilar[index].gorev),
);
},
)
Bu yaklaşım, veriniz değiştikçe arayüzün dinamik olarak güncellenmesini sağlar. kullanicilar listesine yeni bir eleman eklendiğinde, setState kullanarak arayüzü tetikleyebilirsiniz.
Liste Elemanlarını Güncelleme ve Etkileşim
Dinamik bir listede sadece veriyi göstermek yetmez; aynı zamanda veriyi silmek veya güncellemek gerekebilir. Dismissible widget'ı, listelerden eleman silmek için standart ve kullanıcı dostu bir yöntemdir.
Dismissible(
key: Key(kullanicilar[index].isim),
onDismissed: (direction) {
setState(() {
kullanicilar.removeAt(index);
});
},
child: ListTile(title: Text(kullanicilar[index].isim)),
)
Dismissible kullanırken her elemana benzersiz bir Key atamak zorunludur. Aksi takdirde, Flutter liste elemanlarını karıştırabilir ve beklenmedik hatalara yol açabilir.
Performans ve Bellek Yönetimi Karşılaştırması
Liste oluştururken hangi yöntemi seçeceğiniz, verinizin boyutuna ve yapısına bağlıdır. Aşağıdaki tablo, yaygın yöntemlerin karşılaştırmasını sunar.
| Yöntem | Kullanım Alanı | Performans |
|---|---|---|
| ListView | Küçük, sabit listeler | Düşük (Tüm elemanlar yüklenir) |
| ListView.builder | Büyük veya dinamik listeler | Yüksek (Sadece görünenler yüklenir) |
| ListView.separated | Ayırıcı çizgili listeler | Yüksek |
Güvenlik Uyarısı: Dinamik listelerde dışarıdan gelen verileri (API yanıtları gibi) doğrudan arayüzde göstermeden önce mutlaka doğrulayın. Kullanıcı tarafından girilen verilerin listeye eklenmesi durumunda, XSS (Cross-Site Scripting) benzeri açıklar oluşturmamak için verileri temiz (sanitize) bir şekilde işleyin.
Gelişmiş Liste Özelleştirmeleri: ListView.separated
Bazen liste elemanları arasına çizgiler veya boşluklar koymak istersiniz. ListView.separated bu iş için biçilmiş kaftandır. İki ana parametre alır: itemBuilder ve separatorBuilder.
ListView.separated(
itemCount: kullanicilar.length,
separatorBuilder: (context, index) => Divider(color: Colors.grey),
itemBuilder: (context, index) {
return ListTile(title: Text(kullanicilar[index].isim));
},
)
Bu yöntem, listenizin daha düzenli ve okunabilir görünmesini sağlar. Özellikle ayırıcı çizgilerin tasarımı üzerinde tam kontrol sahibi olursunuz.
Sıkça Sorulan Sorular
ListView.builder neden ListView'dan daha iyidir?
ListView.builder "lazy loading" (tembel yükleme) prensibiyle çalışır. Yani sadece ekranda görünen öğeleri oluşturur. 10.000 öğelik bir listeniz olsa bile, uygulama sadece 5-10 tanesini bellekte tutar, bu da uygulamanın donmasını engeller.
Liste elemanlarına nasıl tıklama özelliği eklerim?
ListTile widget'ının onTap parametresini kullanarak tıklama olaylarını yönetebilirsiniz. onTap: () { print("Tıklandı!"); } şeklinde bir fonksiyon atamanız yeterlidir.
Veri listesi güncellendiğinde arayüz neden değişmiyor?
Eğer StatefulWidget kullanıyorsanız, listeyi güncelledikten sonra setState(() {}) fonksiyonunu çağırmalısınız. Bu, Flutter'a arayüzü tekrar çizmesi (rebuild) gerektiğini bildirir.
Key parametresi neden zorunludur?
Key, Flutter'ın widget ağacındaki elemanları takip etmesini sağlar. Özellikle silme veya sıralama gibi işlemlerde, Flutter'ın hangi elemanın hangisi olduğunu karıştırmaması için benzersiz anahtarlar gereklidir.
Çok uzun listelerde kaydırma (scrolling) performansını nasıl artırırım?
ListView.builder içerisinde addAutomaticKeepAlives veya addRepaintBoundaries gibi özellikleri kullanarak performans ince ayarı yapabilirsiniz. Ancak çoğu durumda varsayılan ayarlar yeterlidir.
Liste Görünümlerinde Hata Ayıklama ve Debugging Stratejileri
Dinamik listelerle çalışırken karşılaşılan en yaygın sorunlar genellikle "RangeError", "RenderFlex overflow" veya veri akışındaki senkronizasyon hatalarıdır. Uygulamanızın kararlılığını artırmak için geliştirme sürecinde şu hata ayıklama tekniklerini uygulamalısınız.
Taşma (Overflow) Hatalarını Çözme
Liste elemanları ekran sınırlarını aştığında "RenderFlex overflowed" hatası alırsınız. Bu durum genellikle ListView içinde sabit yükseklikli olmayan bileşenler kullanıldığında veya iç içe geçmiş Expanded widget'larının yanlış yapılandırılmasında ortaya çıkar. Aşağıdaki örnekte, dinamik içerikli bir liste elemanının güvenli bir şekilde nasıl sınırlandırılacağını görebilirsiniz:
Widget build(BuildContext context) {
return ListTile(
title: Text("Uzun Başlık Metni", overflow: TextOverflow.ellipsis),
subtitle: Text("Detaylı açıklama metni...", maxLines: 2, overflow: TextOverflow.fade),
);
}
Liste Veri Akışını İzleme
Veri listesi güncellendiğinde arayüzün tepki vermemesinin temel sebebi, setState() metodunun yanlış yerde çağrılması veya listenin referansının değişmemesidir. Listeyi güncellerken mevcut listeyi temizleyip üzerine eklemek yerine, yeni bir liste referansı atamak Flutter'ın "rebuild" mekanizmasını tetiklemek için daha sağlıklıdır.
Dinamik Listelerde İleri Seviye Performans İpuçları
Büyük veri setleri ile çalışırken, listenin kaydırma performansını (frame rate) korumak için bazı optimizasyon teknikleri hayati önem taşır. Özellikle liste elemanları içerisinde resim veya karmaşık hesaplamalar varsa, bu işlemlerin ana iş parçacığını (UI thread) bloke etmemesi gerekir.
RepaintBoundary Kullanımı
Karmaşık bir liste elemanınız varsa, bu elemanı RepaintBoundary widget'ı ile sarmalayarak Flutter'ın gereksiz yere tüm listeyi yeniden boyamasını engelleyebilirsiniz. Bu, özellikle animasyonlu listelerde CPU kullanımını ciddi oranda düşürür.
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return RepaintBoundary(
child: CustomComplexListItem(data: items[index]),
);
},
)
Görüntü (Image) Optimizasyonu
Listelerde ağdan gelen resimleri kullanırken CachedNetworkImage kütüphanesini tercih etmek, belleği verimli kullanmanızı sağlar. Standart Image.network kullanımı, her kaydırma hareketinde resmin tekrar indirilmesine veya bellekte şişmeye neden olabilir. Bellek sızıntılarını önlemek için ListView içinde cacheExtent parametresini kullanarak, ekranın hemen dışındaki elemanların ne kadarının bellekte tutulacağını kontrol edebilirsiniz.
| Parametre | Açıklama |
|---|---|
cacheExtent |
Ekran dışındaki elemanların piksel cinsinden önbellek alanı. |
addAutomaticKeepAlives |
Elemanların durumunu (state) korumak için kullanılır. |
physics |
Kaydırma davranışını (Bouncing, Clamping) belirler. |
Sonuç
Flutter ile dinamik listeler oluşturmak, mobil uygulama geliştirme sürecinin temel taşıdır. ListView.builder ve ListView.separated kullanarak hem performanslı hem de kullanıcı dostu arayüzler tasarlayabilirsiniz. Veri modelleri ile çalışmak, uygulamanızın daha temiz ve yönetilebilir olmasını sağlar.
Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanacağınız verilerin güvenliğini sağlamak, API'lerden gelen verileri doğrulamak ve hata yönetimi (error handling) mekanizmalarını kurmak tamamen geliştiricinin sorumluluğundadır.
Bir sonraki adım olarak, bu listelere FutureBuilder ekleyerek uzak bir API'den gerçek zamanlı veri çekmeyi öğrenebilirsiniz. Uygulamanızı daha dinamik hale getirmek için veritabanı entegrasyonları ve state management (durum yönetimi) kütüphanelerini araştırmanızı öneririm.


Yorumlar (0)
Yorum Yaz