Flutter ListView Kullanımı: Statik ve Dinamik Listeler Oluşturma
Mobil uygulamaların neredeyse tamamında verileri alt alta veya yan yana sıralamak için listeler kullanılır. Flutter'da listeler oluşturmak hem çok esnek hem de performanslıdır.
Flutter'da ekrana sığmayan, kaydırılabilir (scrollable) içerikler oluşturmak istediğimizde kullandığımız en temel araç ListView widget'ıdır. Sadece birkaç elemanı olan statik listelerden, binlerce elemanı olan dinamik veri setlerine kadar her şeyi ListView ile yönetebiliriz.
Flutter'da liste oluşturmanın 3 temel yöntemini ve liste elemanlarını görselleştirmek için kullandığımız ListTile yapısını inceleyeceğiz.
1. Temel Kullanım: Standart ListView
Eğer listenizdeki eleman sayısı azsa (örneğin bir ayarlar menüsü veya 10-15 elemanlı sabit bir liste) standart ListView kullanabilirsiniz. Standart ListView, içindeki tüm elemanları aynı anda belleğe yükler ve çizer.
Kullanım Örneği:
ListView(
padding: const EdgeInsets.all(8),
children: <Widget>[
Container(
height: 50,
color: Colors.amber[600],
child: const Center(child: Text('A Elemanı')),
),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('B Elemanı')),
),
Container(
height: 50,
color: Colors.amber[100],
child: const Center(child: Text('C Elemanı')),
),
],
)
⚠️ Önemli Not: Eğer binlerce verilik bir liste yapacaksanız, bu yöntemi kullanmamalısınız. Tüm verileri aynı anda yüklemeye çalışmak uygulamanızı dondurabilir veya bellek yetersizliğinden çökmesine sebep olabilir.
2. Performansın Zirvesi: ListView.builder
Eğer internetten çektiğiniz uzun bir veriyi (örneğin Twitter akışı, e-posta kutusu) gösterecekseniz ihtiyacınız olan şey ListView.builder'dır.
Bu yapı "tembel yükleme" (lazy loading) mantığıyla çalışır. Sadece ekranda görünen ve görünmek üzere olan elemanları oluşturur. Siz aşağı kaydırdıkça, yukarıda kalan elemanlar bellekten silinir ve yenileri oluşturulur. Bu sayede 10.000 elemanlı bir liste bile sıfır kasma ile çalışır.
Kullanım Örneği:
final List<String> isimler = ['Ali', 'Ayşe', 'Mehmet', 'Fatma', 'Can'];
ListView.builder(
itemCount: isimler.length, // Listenin kaç elemanlı olacağı
itemBuilder: (BuildContext context, int index) {
// index, o an çizilmekte olan elemanın sırasını verir (0, 1, 2...)
return Container(
height: 50,
margin: const EdgeInsets.all(2),
color: Colors.blue[100],
child: Center(
child: Text('${isimler[index]} (Index: $index)'),
),
);
},
)
3. Araya Ayırıcı Koymak: ListView.separated
Eğer liste elemanlarınızın arasına ince bir çizgi (Divider), bir boşluk veya reklam gibi farklı bir widget koymak isterseniz ListView.separated kurtarıcınızdır. ListView.builder'ın sunduğu tüm performans avantajlarına sahiptir.
Ekstra olarak separatorBuilder adında bir parametre alır ve her elemanın arasına burada belirttiğiniz widget'ı koyar.
Kullanım Örneği:
ListView.separated(
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Öğe $index'),
);
},
separatorBuilder: (BuildContext context, int index) {
// Her elemanın arasına ince gri bir çizgi çizer
return const Divider(color: Colors.grey);
},
)
4. Liste Elemanlarını Tasarlamak: ListTile
Liste elemanlarını oluştururken her seferinde Row'lar ve Column'lar ile sıfırdan tasarım yapmak yorucu olabilir. Flutter, özellikle listeler için tasarlanmış, Material Design standartlarına uygun ListTile widget'ını sunar.
ListTile, bir liste elemanını mantıksal bölgelere ayırır:
leading: En soldaki ikon veya profil fotoğrafı.
title: Ana başlık.
subtitle: Başlığın altındaki alt metin.
trailing: En sağdaki ikon (örneğin bir ok işareti veya favori butonu).
Kullanım Örneği:
ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return Card( // Liste elemanlarına hafif bir gölge ve kart görünümü verir
child: ListTile(
leading: CircleAvatar(
child: Text('${index + 1}'),
),
title: Text('Kullanıcı Adı $index'),
subtitle: const Text('Bu kullanıcının kısa açıklaması burada yer alır.'),
trailing: const Icon(Icons.arrow_forward_ios),
onTap: () {
// Elemana tıklandığında yapılacak işlemler
print('Tıklandı: $index');
},
),
);
},
)
Özetle Ne Öğrendik?
Sabit ve az elemanlı listeler için
ListViewkullanıyoruz.Uzun, dinamik ve performans gerektiren listeler için
ListView.builderkullanıyoruz.Elemanlar arasına ayırıcı çizgiler eklemek için
ListView.separatedtercih ediyoruz.Liste elemanlarını şık ve hızlı bir şekilde tasarlamak için
ListTilewidget'ından faydalanıyoruz.
📘 Flutter’da Listeler (List & ListView)
1️⃣ Liste (List) Nedir?
Liste, birden fazla veriyi tek bir değişken içinde saklamamızı sağlar.
🎯 Örnek:
List<String> meyveler = ["Elma", "Armut", "Muz"];
Bu liste 3 eleman içerir.
2️⃣ Liste Türleri
🔹 String Listesi
List<String> isimler = ["Ahmet", "Mehmet", "Ayşe"];
🔹 Integer Listesi
List<int> sayilar = [10, 20, 30];
🔹 Dinamik Liste
List karisik = ["Ali", 15, true];
⚠️ Gerçek projelerde tip belirtmek daha güvenlidir.
3️⃣ Liste Metotları (Çok Önemli)
➕ Eleman Ekleme
isimler.add("Fatma");
➖ Eleman Silme
isimler.remove("Ahmet");
🔢 Index ile erişim
print(isimler[0]); // İlk eleman
📏 Uzunluk
print(isimler.length);
🖥️ 4️⃣ Flutter’da Listeyi Ekranda Gösterme
Normal Dart listesi oluşturduk ama bunu ekranda göstermek için:
👉 ListView kullanılır.
🧱 5️⃣ ListView Nedir?
Ekranda kaydırılabilir liste oluşturmamızı sağlar.
🔹 Basit ListView Örneği
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: ListeOrnek(),
debugShowCheckedModeBanner: false,
));
}
class ListeOrnek extends StatelessWidget {
final List<String> meyveler = ["Elma", "Armut", "Muz", "Çilek"];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Meyve Listesi")),
body: ListView(
children: meyveler.map((meyve) {
return ListTile(
title: Text(meyve),
);
}).toList(),
),
);
}
}
🚀 6️⃣ ListView.builder (Performans İçin Önemli)
Gerçek projelerde büyük listeler olur (1000+ veri).
Bu yüzden:
👉 ListView.builder kullanılır.
🔹 Builder Örneği
body: ListView.builder(
itemCount: meyveler.length,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.apple),
title: Text(meyveler[index]),
);
},
),
🔎 Açıklama:
| Parametre | Ne işe yarar |
|---|---|
| itemCount | Kaç eleman var |
| itemBuilder | Her satırı üretir |
| index | O anki elemanın sıra numarası |
🎨 7️⃣ ListTile Özelleştirme
ListTile(
leading: Icon(Icons.person),
title: Text("Ahmet"),
subtitle: Text("Öğrenci"),
trailing: Icon(Icons.arrow_forward),
)
| Özellik | Açıklama |
|---|---|
| leading | Soldaki ikon |
| title | Ana yazı |
| subtitle | Alt yazı |
| trailing | Sağdaki ikon |
8️⃣ Tıklanabilir Liste
ListTile(
title: Text(meyveler[index]),
onTap: () {
print("${meyveler[index]} seçildi");
},
)
🔄 9️⃣ Dinamik Liste (StatefulWidget)
Liste değişiyorsa StatefulWidget kullanılır.
➕ Eleman Ekleme Örneği
class ListeOrnek extends StatefulWidget {
@override
_ListeOrnekState createState() => _ListeOrnekState();
}
class _ListeOrnekState extends State<ListeOrnek> {
List<String> meyveler = ["Elma", "Armut"];
void meyveEkle() {
setState(() {
meyveler.add("Yeni Meyve");
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Dinamik Liste")),
body: ListView.builder(
itemCount: meyveler.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(meyveler[index]),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: meyveEkle,
child: Icon(Icons.add),
),
);
}
}
🗑️ 1️⃣0️⃣ Eleman Silme
onTap: () {
setState(() {
meyveler.removeAt(index);
});
}
🏆 1️⃣1️⃣ Gerçek Proje Örneği (Öğrenci Listesi)
class Ogrenci {
String ad;
int yas;
Ogrenci(this.ad, this.yas);
}
Liste:
List<Ogrenci> ogrenciler = [
Ogrenci("Ali", 15),
Ogrenci("Ayşe", 16),
];
Builder:
ListView.builder(
itemCount: ogrenciler.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(ogrenciler[index].ad),
subtitle: Text("Yaş: ${ogrenciler[index].yas}"),
);
},
)
⚡ 1️⃣2️⃣ Önemli Kavramlar
| Kavram | Anlamı |
|---|---|
| List | Veri tutar |
| ListView | Listeyi ekranda gösterir |
| builder | Performanslı liste üretir |
| setState | Ekranı yeniler |
| index | Sıra numarası |
🎯 Sonuç
Flutter’da liste konusu:
🔹 Veri tutma (List)
🔹 Ekrana yazdırma (ListView)
🔹 Dinamik güncelleme (StatefulWidget)
🔹 Performans (ListView.builder)
mantığını öğrenmek demektir.
🎨 Flutter’da Modern Material 3 Liste Tasarımı
1️⃣ Material 3 Nedir?
Material 3 (Material You), Google’ın yeni tasarım sistemidir.
Özellikleri:
Daha yuvarlak köşeler
Dinamik renk sistemi
Daha modern butonlar
Soft gölgeler
Daha sade AppBar
Flutter’da aktif etmek için:
theme: ThemeData(
useMaterial3: true,
),
🏗️ 2️⃣ Modern Liste Uygulaması (Görev Listesi Örneği)
Aşağıdaki örnekte:
✅ Material 3 aktif
✅ Modern Card tasarım
✅ Checkbox
✅ Silme butonu
✅ FloatingActionButton
✅ Soft shadow + yuvarlak köşe
📦 TAM ÇALIŞAN KOD
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
colorSchemeSeed: Colors.blue,
brightness: Brightness.light,
),
home: const ModernListe(),
);
}
}
class Gorev {
String baslik;
bool tamamlandi;
Gorev(this.baslik, {this.tamamlandi = false});
}
class ModernListe extends StatefulWidget {
const ModernListe({super.key});
@override
State<ModernListe> createState() => _ModernListeState();
}
class _ModernListeState extends State<ModernListe> {
final List<Gorev> gorevler = [
Gorev("Flutter çalış"),
Gorev("Matematik tekrar et"),
Gorev("Spor yap"),
];
void gorevEkle() {
setState(() {
gorevler.add(Gorev("Yeni Görev"));
});
}
void gorevSil(int index) {
setState(() {
gorevler.removeAt(index);
});
}
void gorevDurumDegistir(int index, bool? value) {
setState(() {
gorevler[index].tamamlandi = value!;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Modern Görev Listesi"),
centerTitle: true,
),
body: ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: gorevler.length,
itemBuilder: (context, index) {
final gorev = gorevler[index];
return Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
margin: const EdgeInsets.only(bottom: 16),
child: ListTile(
contentPadding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 10),
leading: Checkbox(
value: gorev.tamamlandi,
onChanged: (value) =>
gorevDurumDegistir(index, value),
),
title: Text(
gorev.baslik,
style: TextStyle(
fontSize: 18,
decoration: gorev.tamamlandi
? TextDecoration.lineThrough
: null,
),
),
trailing: IconButton(
icon: const Icon(Icons.delete_outline),
onPressed: () => gorevSil(index),
),
),
);
},
),
floatingActionButton: FloatingActionButton.extended(
onPressed: gorevEkle,
icon: const Icon(Icons.add),
label: const Text("Ekle"),
),
);
}
}
3️⃣ Bu Tasarım Neden Modern?
| Özellik | Neden Modern? |
|---|---|
| useMaterial3: true | Yeni tasarım sistemi |
| colorSchemeSeed | Otomatik renk üretimi |
| RoundedRectangleBorder(20) | Yuvarlak köşe |
| FloatingActionButton.extended | Modern FAB |
| Soft elevation (2) | Yumuşak gölge |
🎨 4️⃣ Renkleri Profesyonel Yapma
Eğer Healthy Living App gibi proje yapıyorsan şunu kullanabilirsin:
colorSchemeSeed: Colors.teal,
veya
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
),
Bu otomatik olarak:
Primary
Secondary
Surface
Background
renklerini üretir.
🚀 5️⃣ Daha Profesyonel Görünüm İçin
Ekleyebileceğimiz gelişmiş özellikler:
✅ Search Bar (AppBar içine)
✅ Swipe ile silme (Dismissible)
✅ AnimatedContainer animasyonu
✅ BottomNavigationBar
✅ Dark Mode toggle
✅ Glassmorphism efekt
✅ Firebase bağlantılı modern liste
Süper Nuri 🚀
Şimdi sana Material 3 + Dark Mode (karanlık mod geçişi) olan modern ve profesyonel bir Flutter yapısını öğretiyorum.
Bu yapı:
✅ Material 3 aktif
✅ Light & Dark tema
✅ Tema değiştirme butonu
✅ Modern AppBar
✅ ColorScheme.fromSeed kullanımı
✅ Üretim kalitesinde yapı
🎨 1️⃣ Material 3 + Dark Mode Mantığı
Flutter’da karanlık mod için:
theme→ Light temadarkTheme→ Dark temathemeMode→ Hangisi aktif?
Ama önemli nokta:
👉 Tema değişimini yönetmek için StatefulWidget kullanacağız.
🏗️ 2️⃣ Profesyonel Tema Yapısı
📦 TAM ÇALIŞAN KOD
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ThemeMode _themeMode = ThemeMode.light;
void _toggleTheme() {
setState(() {
_themeMode =
_themeMode == ThemeMode.light
? ThemeMode.dark
: ThemeMode.light;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
// 🌞 Light Tema
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.teal,
brightness: Brightness.light,
),
),
// 🌙 Dark Tema
darkTheme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.teal,
brightness: Brightness.dark,
),
),
themeMode: _themeMode,
home: AnaSayfa(toggleTheme: _toggleTheme),
);
}
}
class AnaSayfa extends StatelessWidget {
final VoidCallback toggleTheme;
const AnaSayfa({super.key, required this.toggleTheme});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Material 3 Dark Mode"),
centerTitle: true,
actions: [
IconButton(
icon: const Icon(Icons.dark_mode),
onPressed: toggleTheme,
),
],
),
body: Center(
child: Card(
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
child: Padding(
padding: const EdgeInsets.all(30),
child: Column(
mainAxisSize: MainAxisSize.min,
children: const [
Icon(Icons.nightlight_round, size: 50),
SizedBox(height: 15),
Text(
"Tema Değiştirilebilir",
style: TextStyle(fontSize: 20),
),
],
),
),
),
),
);
}
}
3️⃣ Bu Yapı Neden Profesyonel?
| Özellik | Sebep |
|---|---|
| StatefulWidget (MyApp) | Tema global yönetiliyor |
| ThemeMode | Light/Dark kontrol |
| ColorScheme.fromSeed | Otomatik modern renk |
| useMaterial3 | Yeni tasarım sistemi |
| Rounded 24px Card | Modern UI |
🎨 4️⃣ Healthy Living App İçin Öneri
Senin Healthy Living Tracker uygulamana bunu şöyle entegre edebiliriz:
🌙 Kullanıcı tercihini SharedPreferences ile kaydetme
📊 Dark mode’a özel grafik renkleri
🥗 Soft yeşil tonlu sağlık teması
🧠 Sistem temasını otomatik algılama (
ThemeMode.system)
🚀 5️⃣ Daha Profesyonel Seviye
Bir üst seviyede:
✅ Tema animasyonlu geçiş
✅ Custom TextTheme
✅ Custom ElevatedButtonTheme
✅ Material 3 NavigationBar
✅ Dinamik renk (Android 12+)
Yorumlar
Yorum Gönder