Flutter TextField Rehberi: Validasyon, Stil ve İleri Seviye Özellikler
TextField, kullanıcının metin girmesine olanak tanıyan temel bir input bileşenidir. Ancak işin içine girdiğimizde, sadece bir kutudan ibaret olmadığını; doğrulama, stil ve kullanıcı deneyimi (UX) için onlarca parametre barındırdığını görüyoruz.
📌 Flutter TextField ve Özellikleri
Kullanıcıdan Metin Alma Rehberi (Detaylı Anlatım)
Flutter’da kullanıcıdan veri almak, formlar oluşturmak ve etkileşimli arayüzler tasarlamak için en temel yapı taşlarından biri TextField widget’ıdır. Giriş alanları; kullanıcı adı, şifre, arama kutusu, yorum alanı gibi pek çok senaryoda kullanılır.
Bu makalede TextField’ı:
Temel kullanımıyla
Görsel özelleştirmeleriyle
Davranış (event) yönetimiyle
Form ve validasyon mantığıyla
detaylı şekilde inceleyeceğiz.
1️⃣ TextField Nedir?
TextField, kullanıcıdan tek satır veya çok satırlı metin girişi almak için kullanılan bir Flutter widget’ıdır.
📌 Özellikleri:
Klavye türü belirlenebilir
Metin biçimi kontrol edilebilir
Anlık değişimler yakalanabilir
Tamamen özelleştirilebilir
2️⃣ En Temel TextField Kullanımı
TextField(),
Bu haliyle:
Boş bir giriş alanı oluşturur
Herhangi bir kontrol veya stil içermez
📌 Genellikle bu kullanım yetersizdir, mutlaka özellik eklenir.
3️⃣ TextField İçine Açıklama (hintText) Ekleme
TextField(
decoration: InputDecoration(
hintText: "Adınızı giriniz",
),
),
🔹 hintText: Kullanıcı yazmaya başlamadan önce görünen açıklama metni
4️⃣ Label ve Border Kullanımı
TextField(
decoration: InputDecoration(
labelText: "E-posta",
border: OutlineInputBorder(),
),
),
📌 Bu kullanım:
Daha profesyonel
Material Design uyumlu
Formlar için idealdir
5️⃣ İkon Ekleme (Prefix & Suffix)
TextField(
decoration: InputDecoration(
labelText: "Kullanıcı Adı",
prefixIcon: Icon(Icons.person),
suffixIcon: Icon(Icons.check),
),
),
🔹 prefixIcon: Başta ikon
🔹 suffixIcon: Sonda ikon
6️⃣ TextEditingController Kullanımı
Kullanıcının girdiği metni okumak ve yönetmek için kullanılır.
TextEditingController controller = TextEditingController();
TextField(
controller: controller,
),
Metni almak için:
print(controller.text);
📌 Form işlemlerinde olmazsa olmazdır.
7️⃣ Klavye Türünü Değiştirme
TextField(
keyboardType: TextInputType.emailAddress,
),
🔹 Yaygın klavye türleri:
textnumberphoneemailAddressurl
8️⃣ Şifre Alanı (Gizli Metin)
TextField(
obscureText: true,
decoration: InputDecoration(
labelText: "Şifre",
),
),
📌 obscureText: true → Yazılan karakterleri gizler
9️⃣ Maksimum Karakter Sınırı
TextField(
maxLength: 20,
),
🔹 Kullanıcıyı sınırlar
🔹 Otomatik sayaç gösterir
🔟 Çok Satırlı TextField
TextField(
maxLines: 4,
),
📌 Yorum, açıklama, mesaj alanları için idealdir.
1️⃣1️⃣ Anlık Değişimleri Yakalama (onChanged)
TextField(
onChanged: (value) {
print(value);
},
),
📌 Kullanıcı her harf yazdığında tetiklenir
📌 Arama (search) alanlarında çok kullanılır
1️⃣2️⃣ Gönderme Tuşunu Yakalama (onSubmitted)
TextField(
onSubmitted: (value) {
print("Girilen değer: $value");
},
),
🔹 Enter / Done tuşuna basıldığında çalışır
1️⃣3️⃣ TextField Stil Özelleştirme
TextField(
style: TextStyle(
fontSize: 18,
color: Colors.blue,
),
),
1️⃣4️⃣ TextAlign ve Metin Hizalama
TextField(
textAlign: TextAlign.center,
),
1️⃣5️⃣ Enabled / ReadOnly Kullanımı
TextField(
enabled: false,
),
TextField(
readOnly: true,
),
🔹 enabled: false → Tamamen pasif
🔹 readOnly: true → Seçilebilir ama yazılamaz
1️⃣6️⃣ TextField vs TextFormField
| Özellik | TextField | TextFormField |
|---|---|---|
| Basit kullanım | ✅ | ❌ |
| Validasyon | ❌ | ✅ |
| Form yapısı | ❌ | ✅ |
📌 Form kullanıyorsan TextFormField önerilir.
🎯 Ne Zaman TextField Kullanmalıyım?
✔ Arama kutusu
✔ Basit giriş alanları
✔ Anlık veri takibi
❌ Validasyon gerekiyorsa → TextFormField
🧠 Özet
TextField, Flutter’da kullanıcı girişi için temel widget’tırGörsel ve işlevsel olarak tamamen özelleştirilebilir
controllerile veri kontrol edilirForm işlemleri için
TextFormFieldtercih edilir
1. Temel Kullanım ve Veri Alma
Bir TextField'dan veri almanın iki ana yolu vardır:
onChanged: Her karakter değişiminde tetiklenir. Hızlı aramalar için idealdir.
TextEditingController: Metni kontrol etmek, temizlemek veya başlangıç değeri atamak için en sağlıklı yöntemdir.
final TextEditingController _controller = TextEditingController();
TextField(
controller: _controller,
onChanged: (text) {
print("Güncel metin: $text");
},
)
2. Görsel Özelleştirme: InputDecoration
TextField'ın dış görünüşünü (placeholder, kenarlıklar, ikonlar) decoration parametresi ile yönetiriz.
labelText: Kutunun üzerinde duran açıklama.
hintText: Kutu boşken görünen ipucu metni.
prefixIcon / suffixIcon: Metnin başına veya sonuna ikon ekleme.
border:
OutlineInputBorderveyaUnderlineInputBorderseçenekleri.
3. Klavye ve Girdi Kontrolleri
Kullanıcı deneyimini iyileştirmek için klavye tipini ve metin davranışını sınırlamak çok önemlidir:
| Parametre | Açıklama |
| keyboardType | Sayısal (number), E-posta (emailAddress) veya Telefon klavyesi açar. |
| obscureText | Şifre girişleri için metni gizler (nokta şeklinde gösterir). |
| textInputAction | Klavyedeki "Enter" tuşunun görevini belirler (Ara, Gönder, Sonraki). |
| maxLength | Girilebilecek maksimum karakter sayısını belirler. |
4. Stil ve Biçimlendirme (TextStyle & Formatters)
Metnin rengini, font boyutunu değiştirebilir veya kullanıcının sadece belirli formatlarda yazmasını sağlayabilirsiniz.
style: Yazılan metnin rengi, boyutu ve fontu.
inputFormatters: Örneğin sadece rakam girilmesini veya bir kredi kartı formatında (0000 0000...) yazılmasını zorunlu kılar.
TextField(
style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
inputFormatters: [FilteringTextInputFormatter.digitsOnly], // Sadece rakam
)
5. Odak Yönetimi (FocusNode)
Bir formda "Sonraki" butonuna basınca diğer kutucuğa geçmek istiyorsanız FocusNode kullanmanız gerekir.
İpucu:
autofocus: trueyaparak sayfa açılır açılmaz klavyenin otomatik olarak bu kutu için açılmasını sağlayabilirsiniz.
6. TextField vs TextFormField
Eğer bir form yapısı (validasyon/doğrulama gerektiren) kuruyorsanız TextFormField kullanmalısınız.
TextFormField, içinde birvalidatorfonksiyonu barındırır.Boş bırakılamaz veya "geçerli bir e-posta değil" gibi uyarıları otomatik yönetir.
Özet: İdeal Bir TextField Yapılandırması
TextField(
controller: _myController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'E-posta Adresiniz',
hintText: 'ornek@mail.com',
prefixIcon: Icon(Icons.email),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
filled: true,
fillColor: Colors.grey[200],
),
)🎨 Material 3 Uyumlu Flutter TextField Tasarımı
Modern, Dinamik ve Tema Destekli Giriş Alanları
Material 3, Google tarafından geliştirilen ve dinamik renkler, yumuşak köşeler ve erişilebilirlik odaklı yeni nesil tasarım sistemidir.
Flutter’da Material 3 kullanırken TextField’lar da bu sisteme otomatik olarak uyum sağlayabilir — doğru tema ayarlarıyla.
1️⃣ Material 3 Nedir? (Kısa Hatırlatma)
Material 3 (Material You):
🎨 Dinamik renk sistemi (ColorScheme)
🟦 Daha büyük radius (oval kenarlar)
🧩 Daha sade ve modern input alanları
♿ Daha iyi kontrast & erişilebilirlik
📌 Flutter’da Material 3 varsayılan olarak kapalıdır, açmamız gerekir.
2️⃣ Material 3’ü Projede Aktif Etme (EN KRİTİK ADIM)
MaterialApp(
theme: ThemeData(
useMaterial3: true,
),
home: MyHomePage(),
);
✅ Bu satır olmadan Material 3 TextField görünümü gelmez
3️⃣ Material 3 Varsayılan TextField Görünümü
TextField(
decoration: InputDecoration(
labelText: "Ad Soyad",
),
),
📌 Material 3 ile otomatik olarak:
Label animasyonlu
Daha yuvarlak kenarlar
Daha sade border
Modern boşluklar
4️⃣ Material 3’e Uygun Outline Border Tasarımı
TextField(
decoration: InputDecoration(
labelText: "E-posta",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
),
),
),
🎯 Material 3 önerisi:borderRadius: 12 – 20 arası
5️⃣ Focused & Enabled Border (Material 3 Stilinde)
TextField(
decoration: InputDecoration(
labelText: "Kullanıcı Adı",
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide(
color: Colors.grey.shade400,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide(
color: Colors.deepPurple,
width: 2,
),
),
),
),
📌 Odaklanınca daha belirgin ve yumuşak geçişli görünür
6️⃣ Material 3 + ColorScheme Kullanımı (ÖNERİLEN YOL)
ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
),
);
Ardından TextField:
TextField(
decoration: InputDecoration(
labelText: "Telefon",
),
),
🎨 Renkler:
Primary
OnSurface
Outline
otomatik olarak ayarlanır ✔
7️⃣ Material 3 İkonlu TextField Tasarımı
TextField(
decoration: InputDecoration(
labelText: "E-posta",
prefixIcon: Icon(Icons.email_outlined),
),
),
📌 Material 3’te ikonlar:
Daha sade
Daha ince
Göz yormayan tonlarda
8️⃣ Filled TextField (Material 3 Stil)
TextField(
decoration: InputDecoration(
labelText: "Adres",
filled: true,
fillColor: Theme.of(context)
.colorScheme
.surfaceContainerHighest,
),
),
🎯 Material 3’te filled input çok yaygındır
Özellikle:
Mobil formlar
Tablet / Etkileşimli tahta arayüzleri
9️⃣ Şifre Alanı – Material 3 Uyumlu
TextField(
obscureText: true,
decoration: InputDecoration(
labelText: "Şifre",
prefixIcon: Icon(Icons.lock_outline),
),
),
🔟 Material 3 TextField Tema Seviyesinde Özelleştirme
ThemeData(
useMaterial3: true,
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
),
floatingLabelBehavior: FloatingLabelBehavior.auto,
),
);
📌 Böylece tüm TextField’lar otomatik bu stilde olur
1️⃣1️⃣ Material 3 – TextField vs Eski Material 2
| Özellik | Material 2 | Material 3 |
|---|---|---|
| Köşe yapısı | Keskin | Yuvarlak |
| Renk | Sabit | Dinamik |
| Dolgu (filled) | Az | Yaygın |
| Erişilebilirlik | Orta | Yüksek |
🎯 Eğitim Ortamları İçin Öneri (ETAP / Tablet)
✔ Büyük radius
✔ Filled TextField
✔ ColorScheme.fromSeed
✔ Yüksek kontrast
🧠 Özet
useMaterial3: trueşartColorSchemeile dinamik renklerBüyük radius + sade border
Filled TextField Material 3’ün ruhu
Tema seviyesinde özelleştirme en doğru yaklaşım
Aşağıda Material 3 (Material You) tasarım diline tam uyumlu, Login / Register (Giriş – Kayıt) ekranını;
✔ tema ayarları
✔ validasyon
✔ modern UI
✔ tek dosyada çalışır örnek
şeklinde eğitim + gerçek proje formatında bulacaksın.
🔐 Material 3 Uyumlu Login / Register Formu (Flutter)
Material 3, Google tarafından geliştirilen modern tasarım sistemidir. Flutter’da doğru tema ile Login / Register ekranları otomatik olarak modern, sade ve erişilebilir hale gelir.
1️⃣ Material 3 Tema Ayarı (ZORUNLU)
MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
),
filled: true,
),
),
home: AuthPage(),
);
2️⃣ Login / Register Yapısı (TabBar ile)
📌 Tek sayfa
📌 Üstte Login – Register sekmeleri
📌 Material 3 uyumlu
3️⃣ AuthPage (Ana Ekran)
class AuthPage extends StatelessWidget {
const AuthPage({super.key});
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: const Text("Hesap İşlemleri"),
centerTitle: true,
bottom: const TabBar(
tabs: [
Tab(text: "Giriş"),
Tab(text: "Kayıt Ol"),
],
),
),
body: const TabBarView(
children: [
LoginForm(),
RegisterForm(),
],
),
),
);
}
}
4️⃣ Login Formu (Material 3 + Validation)
class LoginForm extends StatefulWidget {
const LoginForm({super.key});
@override
State<LoginForm> createState() => _LoginFormState();
}
class _LoginFormState extends State<LoginForm> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(
labelText: "E-posta",
prefixIcon: Icon(Icons.email_outlined),
),
validator: (value) {
if (value == null || value.isEmpty) {
return "E-posta boş olamaz";
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
obscureText: true,
decoration: const InputDecoration(
labelText: "Şifre",
prefixIcon: Icon(Icons.lock_outline),
),
validator: (value) {
if (value == null || value.length < 6) {
return "Şifre en az 6 karakter olmalı";
}
return null;
},
),
const SizedBox(height: 24),
FilledButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Giriş başarılı")),
);
}
},
child: const Text("Giriş Yap"),
),
],
),
),
);
}
}
5️⃣ Register Formu (Kayıt Ol)
class RegisterForm extends StatefulWidget {
const RegisterForm({super.key});
@override
State<RegisterForm> createState() => _RegisterFormState();
}
class _RegisterFormState extends State<RegisterForm> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(
labelText: "Ad Soyad",
prefixIcon: Icon(Icons.person_outline),
),
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(
labelText: "E-posta",
prefixIcon: Icon(Icons.email_outlined),
),
),
const SizedBox(height: 16),
TextFormField(
obscureText: true,
decoration: const InputDecoration(
labelText: "Şifre",
prefixIcon: Icon(Icons.lock_outline),
),
),
const SizedBox(height: 24),
FilledButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Kayıt başarılı")),
);
}
},
child: const Text("Kayıt Ol"),
),
],
),
),
);
}
}
6️⃣ Material 3 Tasarım Özellikleri (Bu Örnekte)
✅ useMaterial3: true
✅ ColorScheme.fromSeed
✅ Filled TextField
✅ Büyük radius (16)
✅ FilledButton (Material 3 buton)
✅ Modern ikonlar
7️⃣ Eğitim & Proje İçin İdeal Kullanım
✔ 11. sınıf Mobil Uygulamalar
✔ Firebase Auth entegrasyonuna hazır
✔ Tablet / ETAP uyumlu
✔ Gerçek uygulamaya dönüştürülebilir
Bir Form yapısı kurarak verileri nasıl kontrol edeceğimizi (Validation) ve kullanıcı hatalarını nasıl engelleyeceğimizi inceleyelim.
1. TextFormField ve Form Kontrolü
Sıradan bir TextField yerine TextFormField kullanmanın en büyük avantajı, tüm girişleri tek bir yerden (GlobalKey ile) kontrol edebilmektir.
Form ve GlobalKey Kurulumu
Öncelikle formun durumunu takip edecek bir anahtar tanımlamalıyız:
final _formKey = GlobalKey<FormState>(); // Formun "kimliği"
String _userEmail = '';
Validator (Doğrulama) Kullanımı
validator fonksiyonu, kullanıcı "Gönder" butonuna bastığında çalışır. Eğer metin uygun değilse bir hata mesajı döner, uygunsa null döner.
Form(
key: _formKey, // Formu anahtara bağlıyoruz
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
labelText: 'E-posta',
border: OutlineInputBorder(),
),
// Doğrulama Mantığı:
validator: (value) {
if (value == null || value.isEmpty) {
return 'Lütfen e-posta adresinizi girin';
}
if (!value.contains('@')) {
return 'Geçerli bir e-posta adresi giriniz';
}
return null;
},
onSaved: (value) => _userEmail = value!,
),
ElevatedButton(
onPressed: () {
// Formu kontrol et:
if (_formKey.currentState!.validate()) {
// Eğer her şey yolundaysa veriyi kaydet
_formKey.currentState!.save();
print("Kaydedilen veri: $_userEmail");
}
},
child: Text('Giriş Yap'),
),
],
),
)
2. InputFormatters: Veriyi Yazılırken Sınırlamak
Kullanıcının yanlış veri girmesini en baştan engellemek, hata mesajı göstermekten daha iyidir. inputFormatters tam da burada devreye girer.
Sadece Rakam İzni:
FilteringTextInputFormatter.digitsOnlyKarakter Sınırı:
LengthLimitingTextInputFormatter(10)Özel Maskeleme: (Örn: Telefon numarası formatı
(5xx) xxx xx xx)
TextFormField(
keyboardType: TextInputType.phone,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly, // Harf girişini engeller
LengthLimitingTextInputFormatter(11), // 11 haneden fazlasını engeller
],
decoration: InputDecoration(hintText: "Telefon Numaranız"),
)
3. FocusNode ile Odak Yönetimi
Özellikle okul projelerinde veya karmaşık formlarda, kullanıcı e-postayı bitirip "İleri" (Next) dediğinde otomatik olarak şifre kutusuna geçmesi istenir.
FocusNode _passwordFocus = FocusNode();
// İlk kutu (E-posta)
TextFormField(
textInputAction: TextInputAction.next, // Klavyede "İleri" butonu gösterir
onFieldSubmitted: (v) {
FocusScope.of(context).requestFocus(_passwordFocus); // Şifre kutusuna odaklan
},
),
// İkinci kutu (Şifre)
TextFormField(
focusNode: _passwordFocus,
obscureText: true,
decoration: InputDecoration(labelText: "Şifre"),
),
Özet Tablo: TextField Güvenliği ve UX
| Özellik | Kullanım Amacı | Önem Derecesi |
| validator | Verinin doğruluğunu (email mi, boş mu?) kontrol eder. | Kritik |
| obscureText | Şifrelerin görünmesini engeller. | Kritik |
| autocorrect | Yanlış yazım düzeltmeyi açar/kapatır (Şifrelerde kapatılmalıdır). | Orta |
| enableSuggestions | Klavye üzerinde kelime önerileri sunar. | Düşük |
Bu yapı, özellikle Pardus ETAP gibi etkileşimli tahta uygulamalarında kullanıcıdan hızlı ve hatasız veri almak için standarttır.
Harika! O zaman şimdiye kadar öğrendiğimiz TextFormField, Form, Validation ve Controller yapılarını bir araya getiren somut bir uygulama yapalım.
Bu örnekte, bir "Öğrenci Kayıt Paneli" hazırlayacağız. Kullanıcı ismi girecek, biz bunu doğrulayacağız ve butona basıldığında listeye anlık olarak ekleyeceğiz.
Öğrenci Kayıt Uygulaması Taslağı
Bu uygulama, hem form yönetimini hem de Flutter'daki State (Durum) yönetimini anlamanı sağlayacak.
import 'package:flutter/material.dart';
class OgrenciKayitSayfasi extends StatefulWidget {
@override
_OgrenciKayitSayfasiState createState() => _OgrenciKayitSayfasiState();
}
class _OgrenciKayitSayfasiState extends State<OgrenciKayitSayfasi> {
final _formKey = GlobalKey<FormState>(); // Formun kontrol anahtarı
final TextEditingController _adController = TextEditingController(); // Metni almak için
List<String> ogrenciListesi = []; // Eklenen isimlerin tutulduğu liste
void _ogrenciEkle() {
// 1. Form doğrulaması yapılıyor mu?
if (_formKey.currentState!.validate()) {
setState(() {
// 2. Listeye yeni ismi ekle
ogrenciListesi.add(_adController.text);
// 3. Yazı alanını temizle
_adController.clear();
});
// Klavyeyi kapat
FocusScope.of(context).unfocus();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Pardus ETAP Öğrenci Kayıt")),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
// --- FORM ALANI ---
Form(
key: _formKey,
child: Row(
children: [
Expanded(
child: TextFormField(
controller: _adController,
decoration: InputDecoration(
labelText: 'Öğrenci Adı Soyadı',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.person),
),
// Doğrulama: Boş bırakılırsa hata ver
validator: (value) {
if (value == null || value.isEmpty) {
return 'İsim boş olamaz!';
}
return null;
},
),
),
SizedBox(width: 10),
ElevatedButton(
onPressed: _ogrenciEkle,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15),
child: Text("EKLE"),
),
),
],
),
),
Divider(height: 40, thickness: 2),
// --- LİSTELEME ALANI ---
Expanded(
child: ogrenciListesi.isEmpty
? Center(child: Text("Henüz öğrenci eklenmedi."))
: ListView.builder(
itemCount: ogrenciListesi.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: CircleAvatar(child: Text("${index + 1}")),
title: Text(ogrenciListesi[index]),
trailing: IconButton(
icon: Icon(Icons.delete, color: Colors.red),
onPressed: () {
setState(() {
ogrenciListesi.removeAt(index);
});
},
),
),
);
},
),
),
],
),
),
);
}
}
Neler Öğrendik? (Kritik Noktalar)
ExpandedKullanımı:ListViewveTextFormFieldgibi widget'larColumniçinde çakışmaması içinExpandedile sarıldı. Bu, özellikle akıllı tahtalarda ekranın verimli kullanılması için önemlidir.setStateGücü: Listeye bir eleman eklediğimizde ekranın anlık olarak güncellenmesi içinsetStatekullandık.ListView.builder: Liste uzadıkça performans kaybı yaşanmaması için elemanları sadece ekrana geldikçe oluşturan bu yapıyı tercih ettik.Hızlı Temizlik:
_adController.clear()ile kullanıcı her ekleme yaptığında kutucuğu bir sonraki giriş için hazırladık.
Bir Sonraki Adım: Veritabanı?
Bu veriler şu an sadece uygulama açıkken RAM'de tutuluyor. Uygulamayı kapatıp açtığında liste sıfırlanacaktır.
Görsel yapı ve temalandırma (UI/UX), bir uygulamanın sadece "çalışan" bir araçtan "keyifle kullanılan" bir deneyime dönüşmesini sağlar. Özellikle Pardus ETAP gibi geniş ekranlı veya akıllı tahta ortamlarında, kontrastı yüksek ve göz yormayan tasarımlar çok önemlidir.
Şimdi TextField ve uygulama genelini ThemeData kullanarak nasıl modernize edebileceğimize bakalım.
1. Merkezi Tema Yönetimi (ThemeData)
Her TextField için tek tek renk tanımlamak yerine, uygulamanın ana temasında (MaterialApp) bir standart belirlemek en profesyonel yaklaşımdır.
MaterialApp(
theme: ThemeData(
primaryColor: Colors.blueGrey[900],
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: Colors.blueGrey[50],
labelStyle: TextStyle(color: Colors.blueGrey[700]),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent, width: 2),
borderRadius: BorderRadius.circular(15),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey),
borderRadius: BorderRadius.circular(15),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2),
borderRadius: BorderRadius.circular(15),
),
),
),
home: OgrenciKayitSayfasi(),
);
2. TextField İçin Görsel İpuçları ve Efektler
Kullanıcı etkileşimini artırmak için şu üç özelliği kullanabiliriz:
A. Floating Label Style (Yüzen Etiket)
Metin kutusuna tıklandığında yukarı kayan etiketin rengini ve stilini floatingLabelStyle ile değiştirebilirsiniz.
B. Gradient Arka Plan (Konteyner ile)
TextField'ı bir Container içine alarak ona degrade (geçişli) renkler verebiliriz.
C. İnteraktif İkonlar
suffixIcon kullanarak şifreyi göster/gizle veya metni temizle butonları eklemek kullanıcı dostudur.
3. Gelişmiş Tasarımlı "Öğrenci Kartı"
Listede görünen her bir öğrenciyi sıradan bir metin yerine, daha şık bir Card yapısına kavuşturalım:
Widget _ogrenciKart(String isim, int index) {
return Container(
margin: EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blueAccent.withOpacity(0.1), Colors.white],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.blueAccent.withOpacity(0.3)),
),
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.blueAccent,
child: Text("${index + 1}", style: TextStyle(color: Colors.white)),
),
title: Text(
isim,
style: TextStyle(fontWeight: FontWeight.bold, letterSpacing: 1.1),
),
trailing: Icon(Icons.chevron_right, color: Colors.blueAccent),
),
);
}
4. Dark Mode (Karanlık Mod) Desteği
Akıllı tahtalarda akşam saatlerinde veya loş ışıkta göz yorgunluğunu önlemek için karanlık mod şarttır. Flutter'da bunu tek satırla ekleyebilirsiniz:
darkTheme: ThemeData.dark().copyWith(
inputDecorationTheme: InputDecorationTheme(
fillColor: Colors.grey[800],
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.amber),
),
),
),
themeMode: ThemeMode.system, // Sistemin ayarına göre otomatik değişir
Tasarım İpucu: Pardus Kurumsal Renkleri
Uygulamanı Pardus ekosistemine daha uygun hale getirmek istersen:
Ana Renk:
#1d2b3a(Koyu Lacivert)Vurgu Rengi:
#f39200(Pardus Turuncusu)
Bu renkleri Color(0xFF1D2B3A) şeklinde kullanarak kurumsal bir görünüm elde edebilirsin.
Yorumlar
Yorum Gönder