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:
value:true(seçili),false(seçili değil) veyanull(belirsiz) değerini alır.onChanged: Kullanıcı kutuya tıkladığında tetiklenen fonksiyondur. Yeni değeri size verir.
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:
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.
| Özellik | Açıklama |
activeColor | Kutu seçili (true) olduğundaki arka plan rengi. |
checkColor | Tik işaretinin rengi. |
fillColor | State'e göre (seçili, pasif vb.) dinamik renk vermek için kullanılır (MaterialStateProperty). |
shape | Kutunun şeklini değiştirir (Örn: Yuvarlak köşeler). |
side | Kutunun kenar çizgisi (border) kalınlığı ve rengi. |
Örnek: Yuvarlak Köşeli ve Kırmızı Checkbox
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)
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.
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
State Yönetimi: Basit uygulamalar için
setStateyeterlidir. Ancak büyük projelerde Checkbox durumlarını yönetmek için Provider, Riverpod veya Bloc kullanmanız önerilir.Erişilebilirlik:
CheckboxListTilekullanmak, tıklama alanını büyüttüğü için erişilebilirliği artırır.Null Safety:
onChangedmetodunda gelen değerbool?(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:
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ı.
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ğilsefalse, karışık isenull).
İş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.
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ı
_tumunuSecDurumuGetir()Fonksiyonu:Bu fonksiyon, her
setStatetetiklendiğ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
nulldöndürür, bu da ekranda checkbox'ın içinde bir "tire (-)" işareti çıkmasını sağlar.
tristate: true:Ana
CheckboxListTileiçerisinde bu parametreyitrueyapmak zorundayız. Aksi takdirdevalueparametresinenullatadığımızda hata alırız.
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._tumunuDegistirfonksiyonundakivalue ?? falsemantığı, belirsizlik durumunda güvenli birbooleandeğ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ı
| Parametre | Açıklama |
|---|---|
value | Checkbox’ın mevcut durumu |
onChanged | Tıklanınca çalışır |
activeColor | İşaretli renk |
checkColor | Tik işareti rengi |
tristate | 3 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.builderGereksiz rebuild önle
constkullanımıWidget ayırma
📌 Checkbox vs Switch
| Checkbox | Switch |
|---|---|
| Ç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:
Yeni bir "Gizlilik Ayarları" kartı ekle
Checkbox ile "Konum Paylaşımı"
Riverpod’a çevir
Local storage (SharedPreferences) ekle
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şen | Light Mode | Dark Mode |
|---|---|---|
| Card | Açık zemin | Koyu yüzey |
| Switch | Canlı primary | Yumuşak primary |
| Checkbox | Daha belirgin | Daha kontrastlı |
| Divider | Açık gri | Yumuş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
Yorum Gönder