Flutter Checkbox : Kapsamlı Kullanım, Tristate ve Örnekler

Checkbox (Onay Kutusu), kullanıcıdan "evet/hayır" veya "seçili/seçili değil" gibi ikili (binary) verileri almak için kullanılan temel bir arayüz elemanıdır. Flutter'da bu widget'ı yönetmek, state (durum) yönetimini anlamak için de harika bir pratiktir.


Flutter'da Checkbox, Material Design prensiplerine uygun olarak oluşturulmuş, etkileşimli bir widget'tır. Bu rehberde, basit bir onay kutusundan özelleştirilmiş listelere kadar her yönünü inceleyeceğiz.

1. Checkbox'ın Temel Mantığı

Flutter'daki çoğu input widget'ı gibi, Checkbox da kendi state'ini (durumunu) tutmaz. Yani kutuya tıkladığınızda görsel olarak "tik" işaretinin gelmesi için sizin value değerini güncellemeniz ve arayüzü setState ile yenilemeniz gerekir.

En Temel Kullanım

Bir StatefulWidget içerisinde şu iki zorunlu parametreyi kullanmalısınız:

  1. value: true (seçili), false (seçili değil) veya null (belirsiz) değerini alır.

  2. onChanged: Kullanıcı kutuya tıkladığında tetiklenen fonksiyondur. Yeni değeri size verir.

Dart
bool _isChecked = false; // State değişkenimiz

Checkbox(
  value: _isChecked,
  onChanged: (bool? newValue) {
    setState(() {
      _isChecked = newValue!; // Değeri güncelle ve arayüzü yenile
    });
  },
)

2. Checkbox vs. CheckboxListTile

Sadece Checkbox kullanmak bazen kullanıcı deneyimi (UX) açısından zayıf kalabilir çünkü tıklama alanı sadece küçük kutu ile sınırlıdır. Genellikle yanında bir metin (Label) olması istenir. İşte burada CheckboxListTile devreye girer.

Neden CheckboxListTile Kullanmalısınız?

  • Daha Geniş Tıklama Alanı: Kullanıcı metne tıkladığında da kutucuk işaretlenir.

  • Hazır Düzen: Metin ve kutu otomatik olarak hizalanır.

  • Ekstra Özellikler: Alt başlık (subtitle) ve ikon (secondary) ekleyebilirsiniz.

Örnek Kod:

Dart
CheckboxListTile(
  title: Text("Bildirimleri Aç"),
  subtitle: Text("Uygulama içi bildirimleri alırsınız."),
  secondary: Icon(Icons.notifications), // Sol tarafa ikon ekler
  value: _bildirimAcikMi,
  onChanged: (bool? value) {
    setState(() {
      _bildirimAcikMi = value!;
    });
  },
  activeColor: Colors.green, // Seçili olduğunda renk
)

3. Görünümü Özelleştirme (Styling)

Checkbox'ı uygulamanızın temasına uydurmak için çeşitli parametreleri kullanabilirsiniz.

ÖzellikAçıklama
activeColorKutu seçili (true) olduğundaki arka plan rengi.
checkColorTik işaretinin rengi.
fillColorState'e göre (seçili, pasif vb.) dinamik renk vermek için kullanılır (MaterialStateProperty).
shapeKutunun şeklini değiştirir (Örn: Yuvarlak köşeler).
sideKutunun kenar çizgisi (border) kalınlığı ve rengi.

Örnek: Yuvarlak Köşeli ve Kırmızı Checkbox

Dart
Checkbox(
  value: _isChecked,
  activeColor: Colors.red,
  checkColor: Colors.white,
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(5), // Hafif yuvarlatılmış köşeler
  ),
  side: BorderSide(
    color: Colors.red, // Seçili değilken çerçeve rengi
    width: 2,
  ),
  onChanged: (val) {
    setState(() => _isChecked = val!);
  },
)

4. Tristate (Üç Durumlu) Checkbox

Bazen bir seçenek sadece "Evet" veya "Hayır" değildir. Örneğin, bir "Tümünü Seç" kutusu düşünün. Listenin yarısı seçiliyse, ana kutu ne seçili ne de seçisiz olmalıdır; belirsiz (indeterminate) olmalıdır.

Bunu yapmak için tristate: true özelliğini kullanırız. Bu durumda value null olabilir.

  • true: Seçili (Tik)

  • false: Seçili değil (Boş)

  • null: Belirsiz (Genellikle bir tire - işareti çıkar)

Dart
bool? _triStateValue = null; // Başlangıçta null (belirsiz)

Checkbox(
  tristate: true, // Üçlü durumu aktif et
  value: _triStateValue,
  onChanged: (bool? newValue) {
    setState(() {
      // Döngüsel mantık: null -> true -> false -> null
      if (_triStateValue == null) {
        _triStateValue = true;
      } else if (_triStateValue == true) {
        _triStateValue = false;
      } else {
        _triStateValue = null;
      }
    });
  },
)

5. Tam Uygulama Örneği: Yapılacaklar Listesi

Aşağıda, öğrendiklerimizi birleştiren, dinamik bir yapılacaklar listesi örneği bulunmaktadır.

Dart
import 'package:flutter/material.dart';

class TodoListOrnegi extends StatefulWidget {
  @override
  _TodoListOrnegiState createState() => _TodoListOrnegiState();
}

class _TodoListOrnegiState extends State<TodoListOrnegi> {
  // Görev listesi verisi
  final List<Map<String, dynamic>> _gorevler = [
    {"isim": "Flutter çalış", "durum": false},
    {"isim": "Spor yap", "durum": true},
    {"isim": "Kitap oku", "durum": false},
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Görev Listesi")),
      body: ListView.builder(
        itemCount: _gorevler.length,
        itemBuilder: (context, index) {
          return Card(
            child: CheckboxListTile(
              title: Text(
                _gorevler[index]["isim"],
                style: TextStyle(
                  // Seçiliyse üzerini çiz
                  decoration: _gorevler[index]["durum"]
                      ? TextDecoration.lineThrough
                      : null,
                  color: _gorevler[index]["durum"] ? Colors.grey : Colors.black,
                ),
              ),
              value: _gorevler[index]["durum"],
              onChanged: (bool? value) {
                setState(() {
                  _gorevler[index]["durum"] = value!;
                });
              },
              controlAffinity: ListTileControlAffinity.leading, // Kutuyu sola alır
              activeColor: Colors.deepPurple,
            ),
          );
        },
      ),
    );
  }
}

İpuçları ve En İyi Uygulamalar

  1. State Yönetimi: Basit uygulamalar için setState yeterlidir. Ancak büyük projelerde Checkbox durumlarını yönetmek için Provider, Riverpod veya Bloc kullanmanız önerilir.

  2. Erişilebilirlik: CheckboxListTile kullanmak, tıklama alanını büyüttüğü için erişilebilirliği artırır.

  3. Null Safety: onChanged metodunda gelen değer bool? (nullable boolean) türündedir. tristate: false (varsayılan) kullanıyorsanız, değeri kullanmadan önce ! ile null olmadığını garanti etmeyi veya bir varsayılan değer atamayı unutmayın.

Bu rehberle Flutter projelerinizde Checkbox'ları profesyonelce kullanmaya başlayabilirsiniz.

Harika! "Tümünü Seç" (Select All) özelliği, Tristate Checkbox mantığını anlamak için en iyi örnektir.

Buradaki mantık iki yönlü çalışmalıdır:

  1. Yukarıdan Aşağıya: "Tümünü Seç" kutusuna tıklandığında, alttaki tüm görevler seçilmeli veya seçimleri kaldırılmalı.

  2. Aşağıdan Yukarıya: Alttaki görevlerden biri değiştiğinde, ana kutunun durumu kontrol edilmeli (Hepsi seçiliyse true, hiçbiri seçili değilse false, karışık ise null).

İşte Tümünü Seç özellikli Yapılacaklar Listesi'nin tam kodları ve açıklaması:

Tam Kod Örneği

Bu kodu direkt olarak main.dart dosyanıza yapıştırıp çalıştırabilirsiniz.

Dart
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: GelismisTodoList(),
    theme: ThemeData(primarySwatch: Colors.deepPurple),
  ));
}

class GelismisTodoList extends StatefulWidget {
  @override
  _GelismisTodoListState createState() => _GelismisTodoListState();
}

class _GelismisTodoListState extends State<GelismisTodoList> {
  // Görev verilerimiz
  final List<Map<String, dynamic>> _gorevler = [
    {"isim": "Flutter çalış", "durum": false},
    {"isim": "Spor yap", "durum": false},
    {"isim": "Kitap oku", "durum": false},
    {"isim": "Markete git", "durum": false},
  ];

  // --- MANTIK FONKSİYONLARI ---

  // 1. Ana Checkbox'ın (Tümünü Seç) o anki durumunu hesaplar
  bool? _tumunuSecDurumuGetir() {
    // Eğer hepsi seçiliyse -> true
    if (_gorevler.every((g) => g["durum"] == true)) {
      return true;
    }
    // Eğer hiçbiri seçili değilse -> false
    if (_gorevler.every((g) => g["durum"] == false)) {
      return false;
    }
    // Karışıksa (bazıları seçili, bazıları değil) -> null (Tristate)
    return null;
  }

  // 2. Ana Checkbox'a tıklandığında çalışır
  void _tumunuDegistir(bool? value) {
    setState(() {
      // Eğer value null gelirse (tristate döngüsünde), false kabul et
      bool yeniDurum = value ?? false; 
      
      // Tüm listeyi yeni duruma göre güncelle
      for (var gorev in _gorevler) {
        gorev["durum"] = yeniDurum;
      }
    });
  }

  // 3. Tekil görevlere tıklandığında çalışır
  void _tekilGorevDegistir(int index, bool? value) {
    setState(() {
      _gorevler[index]["durum"] = value!;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Gelişmiş Todo Listesi")),
      body: Column(
        children: [
          // --- ANA KONTROL KUTUSU (Tümünü Seç) ---
          Container(
            color: Colors.deepPurple.shade50,
            child: CheckboxListTile(
              title: Text(
                "Tümünü Seç",
                style: TextStyle(fontWeight: FontWeight.bold),
              ),
              tristate: true, // ÖNEMLİ: Üçlü durumu aktif ediyoruz
              value: _tumunuSecDurumuGetir(), // Durumu dinamik hesaplıyoruz
              onChanged: _tumunuDegistir, // Toplu değiştirme fonksiyonu
              controlAffinity: ListTileControlAffinity.leading,
              activeColor: Colors.deepPurple,
            ),
          ),
          Divider(height: 1),
          
          // --- GÖREV LİSTESİ ---
          Expanded(
            child: ListView.builder(
              itemCount: _gorevler.length,
              itemBuilder: (context, index) {
                return CheckboxListTile(
                  title: Text(_gorevler[index]["isim"]),
                  value: _gorevler[index]["durum"],
                  onChanged: (val) => _tekilGorevDegistir(index, val),
                  controlAffinity: ListTileControlAffinity.leading,
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

Kodun Kilit Noktaları

  1. _tumunuSecDurumuGetir() Fonksiyonu:

    • Bu fonksiyon, her setState tetiklendiğinde ana checkbox'ın ne durumda olması gerektiğini hesaplar.

    • Dart dilindeki .every() metodu burada çok işe yarar. Listenin tamamının aynı olup olmadığını kontrol eder.

    • Eğer liste karışıksa null döndürür, bu da ekranda checkbox'ın içinde bir "tire (-)" işareti çıkmasını sağlar.

  2. tristate: true:

    • Ana CheckboxListTile içerisinde bu parametreyi true yapmak zorundayız. Aksi takdirde value parametresine null atadığımızda hata alırız.

  3. Kullanıcı Deneyimi (UX):

    • Kullanıcı ana kutuya tıkladığında, o anki durum null (belirsiz) olsa bile, genellikle hepsini seçmek veya hepsini kaldırmak isteriz. _tumunuDegistir fonksiyonundaki value ?? false mantığı, belirsizlik durumunda güvenli bir boolean değere geçmemizi sağlar.


1️⃣ Checkbox Nedir?

Checkbox, iki (veya üç) durumlu bir seçim kontrolüdür:

  • true → İşaretli

  • false → İşaretsiz

  • null → Belirsiz (tristate açık ise)

Flutter’da Checkbox stateless değildir. Seçim durumunu bir bool değişken ile yönetmemiz gerekir.


2️⃣ Temel Checkbox Kullanımı

bool isChecked = false;

Checkbox(
  value: isChecked,
  onChanged: (bool? newValue) {
    setState(() {
      isChecked = newValue!;
    });
  },
)

🔎 Parametre Açıklaması

ParametreAçıklama
valueCheckbox’ın mevcut durumu
onChangedTıklanınca çalışır
activeColorİşaretli renk
checkColorTik işareti rengi
tristate3 durum aktif eder

3️⃣ Tristate (Üç Durumlu Checkbox)

bool? isChecked;

Checkbox(
  value: isChecked,
  tristate: true,
  onChanged: (value) {
    setState(() {
      isChecked = value;
    });
  },
)

Durum sırası:

false → true → null → false

Genellikle "Tümünü Seç" senaryolarında kullanılır.


4️⃣ CheckboxListTile (Profesyonel Kullanım)

Tek başına Checkbox kullanmak yerine genellikle CheckboxListTile tercih edilir.

CheckboxListTile(
  title: Text("Kullanım koşullarını kabul ediyorum"),
  value: isChecked,
  onChanged: (value) {
    setState(() {
      isChecked = value!;
    });
  },
)

Avantajları

  • Başlık

  • Alt başlık

  • İkon

  • Otomatik padding

  • Tıklanabilir tüm alan


5️⃣ Material 3 Uyumlu Tasarım

Flutter 3+ ile Material 3 desteği:

MaterialApp(
  theme: ThemeData(
    useMaterial3: true,
  ),
)

Material 3’te Checkbox daha yumuşak köşeli ve dinamik renk sistemine bağlıdır.


6️⃣ CheckboxTheme ile Global Stil

Tüm uygulamada checkbox stilini değiştirmek için:

theme: ThemeData(
  useMaterial3: true,
  checkboxTheme: CheckboxThemeData(
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(6),
    ),
    side: BorderSide(width: 2),
  ),
),

7️⃣ Form İçinde Kullanımı (Validation ile)

Checkbox’ı bir kayıt formunda kullanalım:

bool acceptTerms = false;

ElevatedButton(
  onPressed: acceptTerms ? () {
    print("Form gönderildi");
  } : null,
  child: Text("Kayıt Ol"),
)

Buton sadece checkbox işaretliyse aktif olur.


8️⃣ Clean Code – Checkbox Widget’a Bölme

Büyük projelerde widget’ı ayırmak iyi pratiktir.

class TermsCheckbox extends StatelessWidget {
  final bool value;
  final Function(bool?) onChanged;

  const TermsCheckbox({
    required this.value,
    required this.onChanged,
  });

  @override
  Widget build(BuildContext context) {
    return CheckboxListTile(
      title: Text("Sözleşmeyi kabul ediyorum"),
      value: value,
      onChanged: onChanged,
    );
  }
}

9️⃣ Çoklu Checkbox Listesi (Dinamik)

List<String> hobbies = ["Yazılım", "Spor", "Müzik"];
Map<String, bool> selected = {};

@override
void initState() {
  super.initState();
  for (var hobby in hobbies) {
    selected[hobby] = false;
  }
}

ListView içinde:

ListView(
  children: hobbies.map((hobby) {
    return CheckboxListTile(
      title: Text(hobby),
      value: selected[hobby],
      onChanged: (value) {
        setState(() {
          selected[hobby] = value!;
        });
      },
    );
  }).toList(),
)

🔟 Mini Proje: Ayarlar Ekranı

  • 🔔 Bildirimleri Aç

  • 🌙 Karanlık Mod

  • 📧 E-posta Güncellemeleri

Bu seçenekleri Checkbox ile oluşturup bir ayarlar sayfası tasarlayabilirsiniz.


🎨 Material 3 Modern Checkbox Tasarım İpuçları

CheckboxListTile kullan
ListTileTheme ile spacing ayarla
Card içinde gruplandır
Padding ile boşluk ver
Theme.of(context).colorScheme kullan


🚀 Provider / Riverpod ile State Yönetimi

Büyük projelerde setState yerine:

  • Provider

  • Riverpod

  • Bloc

kullanmak daha sağlıklıdır.

Checkbox sadece UI’dır, state mantığını ayrı yönetmek gerekir.


🧠 Performans İpuçları

  • Büyük listelerde ListView.builder

  • Gereksiz rebuild önle

  • const kullanımı

  • Widget ayırma


📌 Checkbox vs Switch

CheckboxSwitch
Çoklu seçim        Genelde tek ayar
Liste tipi        Ayar tipi
Daha küçük        Daha belirgin




Tam Material 3 Ayar Ekranı Projesi

Bu projede:

  • ✅ Material 3 tasarım

  • 🌙 Dark / Light mode

  • 🔔 Bildirim ayarları

  • 📧 E-posta tercihleri

  • 🔒 Gizlilik seçenekleri

  • 🧩 Clean Code (Widget’lara bölünmüş yapı)

  • 🗂 State yönetimi (Provider)

tam bir modern Ayarlar Ekranı geliştireceğiz.


🚀 1️⃣ Proje Özellikleri

Ayarlar ekranında:

  • Bildirimleri Aç/Kapat (Switch)

  • E-posta Güncellemeleri (Checkbox)

  • Pazarlama İzni (Checkbox)

  • Karanlık Mod (Switch)

  • Tümünü Seç (Tristate Checkbox)

  • Kaydet Butonu

  • Card gruplama

  • Material 3 uyumlu tasarım


📦 2️⃣ pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.1.2

🏗 3️⃣ main.dart (Material 3 + Theme Yönetimi)

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'settings_provider.dart';
import 'settings_screen.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => SettingsProvider(),
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    final settings = context.watch<SettingsProvider>();

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      themeMode: settings.isDarkMode ? ThemeMode.dark : ThemeMode.light,
      theme: ThemeData(
        useMaterial3: true,
        colorSchemeSeed: Colors.indigo,
        brightness: Brightness.light,
      ),
      darkTheme: ThemeData(
        useMaterial3: true,
        colorSchemeSeed: Colors.indigo,
        brightness: Brightness.dark,
      ),
      home: const SettingsScreen(),
    );
  }
}

🧠 4️⃣ settings_provider.dart

import 'package:flutter/material.dart';

class SettingsProvider extends ChangeNotifier {
  bool notifications = true;
  bool emailUpdates = false;
  bool marketingEmails = false;
  bool isDarkMode = false;

  bool? get allEmails {
    if (emailUpdates && marketingEmails) return true;
    if (!emailUpdates && !marketingEmails) return false;
    return null;
  }

  void toggleNotifications(bool value) {
    notifications = value;
    notifyListeners();
  }

  void toggleEmailUpdates(bool value) {
    emailUpdates = value;
    notifyListeners();
  }

  void toggleMarketing(bool value) {
    marketingEmails = value;
    notifyListeners();
  }

  void toggleDarkMode(bool value) {
    isDarkMode = value;
    notifyListeners();
  }

  void toggleAllEmails(bool? value) {
    emailUpdates = value ?? false;
    marketingEmails = value ?? false;
    notifyListeners();
  }
}

🎨 5️⃣ settings_screen.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'settings_provider.dart';

class SettingsScreen extends StatelessWidget {
  const SettingsScreen({super.key});

  @override
  Widget build(BuildContext context) {
    final settings = context.watch<SettingsProvider>();

    return Scaffold(
      appBar: AppBar(
        title: const Text("Ayarlar"),
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [

          /// BİLDİRİMLER CARD
          Card(
            child: Column(
              children: [
                SwitchListTile(
                  title: const Text("Bildirimleri Aç"),
                  value: settings.notifications,
                  onChanged: settings.toggleNotifications,
                ),
              ],
            ),
          ),

          const SizedBox(height: 16),

          /// E-POSTA CARD
          Card(
            child: Column(
              children: [
                CheckboxListTile(
                  title: const Text("Tüm E-postaları Seç"),
                  tristate: true,
                  value: settings.allEmails,
                  onChanged: settings.toggleAllEmails,
                ),
                const Divider(),

                CheckboxListTile(
                  title: const Text("E-posta Güncellemeleri"),
                  value: settings.emailUpdates,
                  onChanged: (v) =>
                      settings.toggleEmailUpdates(v ?? false),
                ),

                CheckboxListTile(
                  title: const Text("Pazarlama E-postaları"),
                  value: settings.marketingEmails,
                  onChanged: (v) =>
                      settings.toggleMarketing(v ?? false),
                ),
              ],
            ),
          ),

          const SizedBox(height: 16),

          /// TEMA CARD
          Card(
            child: SwitchListTile(
              title: const Text("Karanlık Mod"),
              value: settings.isDarkMode,
              onChanged: settings.toggleDarkMode,
            ),
          ),

          const SizedBox(height: 24),

          FilledButton.icon(
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text("Ayarlar kaydedildi")),
              );
            },
            icon: const Icon(Icons.save),
            label: const Text("Kaydet"),
          )
        ],
      ),
    );
  }
}

🎯 6️⃣ Material 3 Tasarım Özellikleri

useMaterial3: true
colorSchemeSeed ile dinamik renk
FilledButton kullanımı
Card ile grup tasarım
✔ Modern Switch ve Checkbox görünümü


🧩 Clean Code Yapısı

lib/
 ├── main.dart
 ├── settings_provider.dart
 └── settings_screen.dart

Büyük projelerde her Card’ı ayrı widget yapabilirsiniz:

  • NotificationCard

  • EmailCard

  • ThemeCard


🌙 7️⃣ Dark Mode Otomatik Geçiş

Switch değiştiğinde:

themeMode: settings.isDarkMode ? ThemeMode.dark : ThemeMode.light

Uygulama anında tema değiştirir.


📱 8️⃣ UI İyileştirme Önerileri

  • ListTileTheme ile spacing

  • Section başlıkları ekleme

  • Icon’lu başlıklar

  • NavigationRail destekli ayar sayfası

  • Responsive tasarım (Tablet)


🎓 11. Sınıf İçin LAB Görevi

Öğrenciden:

  1. Yeni bir "Gizlilik Ayarları" kartı ekle

  2. Checkbox ile "Konum Paylaşımı"

  3. Riverpod’a çevir

  4. Local storage (SharedPreferences) ekle

  5. JSON export fonksiyonu yaz


🏁 Sonuç

Bu proje ile:

  • Checkbox

  • Switch

  • Tristate

  • Provider

  • Material 3

  • Theme Management

profesyonel seviyede öğrenilmiş olur.


🌙 Dark Mode + ☀ Light Mode Tasarım Varyasyonu

Flutter – Material 3 Profesyonel Tema Yapısı

Bu bölümde:

  • 🎨 Material 3 Light & Dark tasarım farkları

  • 🌈 ColorScheme mantığı

  • 🧩 Kart, Switch, Checkbox stil uyarlaması

  • ✨ Modern UI iyileştirmeleri

  • 📱 Gerçek uygulama teması (üretim kalitesi)

öğreneceğiz.


1️⃣ Material 3 Tema Mantığı

Material 3’te temel yapı:

ThemeData(
  useMaterial3: true,
  colorScheme: ColorScheme.fromSeed(
    seedColor: Colors.indigo,
    brightness: Brightness.light,
  ),
)

Dark Mode:

ThemeData(
  useMaterial3: true,
  colorScheme: ColorScheme.fromSeed(
    seedColor: Colors.indigo,
    brightness: Brightness.dark,
  ),
)

ColorScheme.fromSeed() → Otomatik uyumlu ton üretir.


2️⃣ Light Mode Tasarım Özellikleri ☀

🎨 Renk Yapısı

  • Background → Açık gri / beyaz

  • Surface → Hafif tonlu

  • Primary → Daha canlı

  • Shadow → Daha yumuşak

UI Stili

  • Card elevation düşük

  • Border hafif

  • Switch aktif renk daha parlak


3️⃣ Dark Mode Tasarım Özellikleri 🌙

🎨 Renk Yapısı

  • Background → #121212 benzeri koyu ton

  • Surface → Hafif daha açık koyu

  • Primary → Daha pastel

  • Shadow → Minimal

UI Stili

  • Card elevation artırılabilir

  • Divider daha yumuşak

  • Kontrast çok önemli


4️⃣ Gelişmiş Tema Yapısı (Profesyonel)

🎨 app_theme.dart

import 'package:flutter/material.dart';

class AppTheme {

  static ThemeData lightTheme() {
    final colorScheme = ColorScheme.fromSeed(
      seedColor: Colors.indigo,
      brightness: Brightness.light,
    );

    return ThemeData(
      useMaterial3: true,
      colorScheme: colorScheme,
      scaffoldBackgroundColor: colorScheme.surface,
      cardTheme: CardTheme(
        elevation: 1,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(16),
        ),
      ),
      switchTheme: SwitchThemeData(
        thumbColor: WidgetStatePropertyAll(colorScheme.primary),
      ),
      checkboxTheme: CheckboxThemeData(
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(6),
        ),
      ),
    );
  }

  static ThemeData darkTheme() {
    final colorScheme = ColorScheme.fromSeed(
      seedColor: Colors.indigo,
      brightness: Brightness.dark,
    );

    return ThemeData(
      useMaterial3: true,
      colorScheme: colorScheme,
      scaffoldBackgroundColor: colorScheme.surface,
      cardTheme: CardTheme(
        elevation: 4,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(16),
        ),
      ),
      switchTheme: SwitchThemeData(
        thumbColor: WidgetStatePropertyAll(colorScheme.primary),
      ),
      checkboxTheme: CheckboxThemeData(
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(6),
        ),
      ),
    );
  }
}

5️⃣ main.dart Güncellemesi

return MaterialApp(
  debugShowCheckedModeBanner: false,
  themeMode: settings.isDarkMode ? ThemeMode.dark : ThemeMode.light,
  theme: AppTheme.lightTheme(),
  darkTheme: AppTheme.darkTheme(),
  home: const SettingsScreen(),
);

6️⃣ UI Varyasyon Farkları

BileşenLight ModeDark Mode
CardAçık zeminKoyu yüzey
SwitchCanlı primaryYumuşak primary
CheckboxDaha belirginDaha kontrastlı
DividerAçık griYumuşak koyu

7️⃣ Modern Görünüm İyileştirme

Ayar kart başlığı ekleyelim:

Padding(
  padding: const EdgeInsets.symmetric(vertical: 8),
  child: Text(
    "Bildirim Ayarları",
    style: Theme.of(context).textTheme.titleMedium,
  ),
),

Material 3 typography kullanmış oluruz.


8️⃣ Adaptive System Theme (Otomatik Sistem Modu)

Kullanıcı sistem temasını kullanmak isterse:

themeMode: ThemeMode.system,

Provider’a 3. seçenek ekleyebilirsin:

  • Light

  • Dark

  • System

Enum ile daha profesyonel olur:

enum AppThemeMode { light, dark, system }

9️⃣ Gerçek Uygulama Tasarım İpuçları

✔ Dark modda saf siyah kullanma (#000000 yerine tonal yüzey)
✔ Kontrast oranını kontrol et
✔ Shadow yerine tonal elevation kullan
✔ SurfaceContainer kullan (Material 3 mantığı)
✔ colorScheme.surfaceVariant değerlendir


🔟 Gelişmiş UX Önerisi

Tema değiştiğinde animasyon:

themeAnimationDuration: Duration(milliseconds: 400),

MaterialApp içinde kullanabilirsin.


🎯 Sonuç

Bu varyasyon ile:

  • Profesyonel tema mimarisi

  • Ayrılmış theme dosyası

  • Material 3 uyumlu yapı

  • Dinamik renk üretimi

  • UI kalite artışı

elde etmiş oldun.



Yorumlar

Bu blogdaki popüler yayınlar

Dart Uygulama Sınavı: Pardus ETAP 23 Kurulum Otomasyonu

Dart Programlama Dil Uygulama Sınavı Çalışma Soruları

Pardus Üzerinde Flutter Geliştirme Ortamı Kurulumu