# 18. Hafta — Dinamik Listeler

## Bu hafta ne yapacağız?

Bir market listesini uygulama açıkken büyütecek, ürünleri alındı olarak işaretleyecek ve kaydırarak sileceğiz. Ardından özgün projemizde öncelikli görevler ekleyip tamamlanma oranını hesaplayacak ve kartları sürükleyerek sıralayacağız.

## Kazanımlar

- `List` koleksiyonuna çalışma anında eleman ekleme ve silme
- `ListView.builder` ile veri sayısına göre arayüz üretme
- `CheckboxListTile` ile model durumunu değiştirme
- `Dismissible` ile kaydırarak silme
- `ReorderableListView` ile sıralamayı değiştirme
- Liste verisinden sayaç ve ilerleme oranı hesaplama

## Çözümlü uygulama — Market Listem

### 1. Ürün modeli

```dart
class Urun {
  Urun(this.ad, {this.alindi = false});
  final String ad;
  bool alindi;
}
```

Ürünün adı değişmez; ancak alışveriş sırasında `alindi` bilgisi değişebilir. Bu nedenle ad `final`, durum ise normal `bool` alanıdır.

### 2. Yeni ürün ekleme

Metin önce `trim` ile temizlenir. Boş değer listeye eklenmez. Geçerli ürün eklendikten sonra giriş alanı temizlenir.

```dart
void ekle() {
  final ad = controller.text.trim();
  if (ad.isEmpty) return;
  setState(() {
    urunler.add(Urun(ad));
    controller.clear();
  });
}
```

### 3. Listeyi üretme ve işaretleme

```dart
ListView.builder(
  itemCount: urunler.length,
  itemBuilder: (context, index) {
    final urun = urunler[index];
    return CheckboxListTile(
      value: urun.alindi,
      title: Text(urun.ad),
      onChanged: (deger) =>
          setState(() => urun.alindi = deger ?? false),
    );
  },
)
```

Alınan ürün sayısı ayrıca saklanmaz; listenin güncel hâlinden hesaplanır:

```dart
final alinan = urunler.where((urun) => urun.alindi).length;
```

### 4. Kaydırarak silme

Her satır `Dismissible` ile sarılır. Anahtar, Flutter'ın hangi satırın kaldırıldığını ayırt etmesini sağlar.

```dart
Dismissible(
  key: ValueKey('${urun.ad}-$index'),
  onDismissed: (_) => setState(() => urunler.removeAt(index)),
  child: urunKarti,
)
```

## Gerçek uygulama ekranı

Görüntü, teste “Elma” yazılıp eklendikten ve “Süt” işaretlendikten sonra gerçek Flutter çıktısından alınmıştır.

![Market Listem gerçek Flutter ekranı](../../screenshots/week-18-adapted.png)

## Özgün uygulama — Bugünün Görevleri

Görev modelinde başlık, öncelik ve tamamlanma durumu bulunur. Öncelik için yazım hatalarını azaltan bir `enum` kullanılır.

```dart
enum Oncelik { dusuk, orta, yuksek }

class Gorev {
  Gorev(this.baslik, this.oncelik, {this.tamamlandi = false});
  final String baslik;
  final Oncelik oncelik;
  bool tamamlandi;
}
```

Tamamlanma oranı listedeki güncel veriden hesaplanarak `LinearProgressIndicator` bileşenine verilir.

```dart
final tamamlanan = gorevler.where((g) => g.tamamlandi).length;
final oran = gorevler.isEmpty ? 0.0 : tamamlanan / gorevler.length;
```

Sürükleme bittiğinde eleman eski konumundan çıkarılıp yeni konuma yerleştirilir:

```dart
onReorder: (eski, yeni) => setState(() {
  if (yeni > eski) yeni--;
  final gorev = gorevler.removeAt(eski);
  gorevler.insert(yeni, gorev);
})
```

![Görev Takipçisi gerçek Flutter ekranı](../../screenshots/week-18-original.png)

## Uygulama görevleri

### Kolay — Çanta kontrol listesi

Ders araçlarını ekleyip hazır olanları işaretleyen bir liste geliştirin. Hazır olanların sayısını başlıkta gösterin.

### Orta — Ev ihtiyaçları

Ürün adına miktar alanı ekleyin. Satırı kaydırarak silme ve tüm işaretleri temizleme özelliklerini uygulayın.

### İleri — Haftalık çalışma panosu

Görevlere ders, tarih ve öncelik ekleyin. Tamamlananları filtreleyin, kartları sürükleyerek sıralayın ve derslere göre ilerleme oranı gösterin.

## Test senaryoları

- Boş metin girildiğinde liste değişmemeli.
- Yeni eleman eklendiğinde sayaç artmalı.
- İşaret kaldırıldığında tamamlanan sayısı azalmalı.
- İlk, orta ve son eleman silinebilmeli.
- Sürüklemeden sonra hiçbir eleman kaybolmamalı.
- Boş listede ilerleme hesabı sıfıra bölme hatası vermemeli.

## Geri bildirim ve çözüm erişimi

Öğrenci önce kendi çözümünü gönderir. Geri bildirimden sonra **İpucunu göster** yalnız yöntemi açıklar; **Örnek çözümü göster** çalışan projenin gerçek `lib/main.dart` dosyasını açar. İndirme bağlantısı tam Flutter projesini çevrim dışı kullanım için sunar.

## Kaynak projeler

- Konu uygulaması: `05 - Modelleme ve Listeler/Uygulamalar/Uygulama-18-Alışveriş Listesi`
- Özgün uygulama: `05 - Modelleme ve Listeler/Uygulamalar/Ozgun-18-Görev Takipçisi`
