Flutter & Mobil İle İleri Düzey Çoklu Form Adımlı Kayıt Sihirbazı Nasıl Yapılır?

Flutter & Mobil İle İleri Düzey Çoklu Form Adımlı Kayıt Sihirbazı Nasıl Yapılır?
Flutter & Mobil İle İleri Düzey Çoklu Form Adımlı Kayıt Sihirbazı Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce geliştirme ortamınızın Flutter 3.24 veya daha güncel bir sürümle yapılandırılmış olması gerekir. İleri düzey bir sihirbaz yapısı için flutter_riverpod veya bloc gibi güçlü bir durum yönetimi kütüphanesine ihtiyaç duyacağız. Bu rehberde, kodun okunabilirliğini artırmak adına Riverpod kullanacağız.

  • Flutter SDK (3.24+)
  • IDE: VS Code veya Android Studio
  • State Management: Riverpod (Durum yönetimi için)
  • Form Validasyonu: FormBuilder veya standart Flutter Form widget'ları

Adım 1: Form Veri Modeli ve Durum Yönetimi

Çok adımlı bir formda en önemli konu, verilerin adımlar değişse bile kaybolmamasıdır. Bunun için tüm kayıt verisini tutan bir veri modeli oluşturmalıyız. Bu model, formun nihai durumunu temsil eder.


class RegistrationData {
  final String? fullName;
  final String? email;
  final String? password;
  final String? address;

  RegistrationData({this.fullName, this.email, this.password, this.address});

  RegistrationData copyWith({String? fullName, String? email, String? password, String? address}) {
    return RegistrationData(
      fullName: fullName ?? this.fullName,
      email: email ?? this.email,
      password: password ?? this.password,
      address: address ?? this.address,
    );
  }
}

Yukarıdaki model, copyWith metodu sayesinde verinin immutability (değişmezlik) prensibine uygun şekilde güncellenmesini sağlar. Bu, durum yönetimi kütüphaneleriyle çalışırken hataları minimize eder.

Adım 2: Adım Kontrolcüsü ve StateNotifier Yapısı

Formun hangi adımda olduğunu ve verilerin durumunu yönetmek için bir StateNotifier sınıfına ihtiyacımız var. Bu sınıf, UI katmanından bağımsız olarak iş mantığını yürütür.


class RegistrationNotifier extends StateNotifier {
  RegistrationNotifier() : super(RegistrationData());

  void updateData({String? fullName, String? email, String? password, String? address}) {
    state = state.copyWith(
      fullName: fullName,
      email: email,
      password: password,
      address: address,
    );
  }
}

Bu sınıf, formdaki her bir alan değişikliğinde state nesnesini günceller. Böylece kullanıcı geri dönüp bir önceki adıma geçtiğinde veriler hazır bir şekilde bekler.

Adım 3: Çoklu Adımlı Arayüz Tasarımı (Stepper)

Flutter'ın kendi Stepper widget'ı basit işler için yeterli olsa da, ileri düzey projelerde kendi özelleştirilebilir yapınızı kurmanız önerilir. Aşağıda, her adımın ayrı bir widget olduğu modüler bir yapı örneği yer almaktadır.


class RegistrationStepper extends StatefulWidget {
  @override
  _RegistrationStepperState createState() => _RegistrationStepperState();
}

class _RegistrationStepperState extends State {
  int _currentStep = 0;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(
          child: _currentStep == 0 ? PersonalInfoStep() : AddressInfoStep(),
        ),
        Row(
          children: [
            if (_currentStep > 0) ElevatedButton(onPressed: () => setState(() => _currentStep--), child: Text("Geri")),
            ElevatedButton(onPressed: () => setState(() => _currentStep++), child: Text("İleri")),
          ],
        )
      ],
    );
  }
}

Bu yapı, her adımı izole eder. PersonalInfoStep ve AddressInfoStep kendi içinde TextFormField bileşenlerini barındırır ve veriyi ana state'e aktarır.

Adım 4: Form Validasyonu ve Güvenlik Önlemleri

Kullanıcı girişlerini doğrulamak, uygulamanın güvenliği ve veri kalitesi için zorunludur. Her adımda GlobalKey kullanarak validasyon işlemlerini yönetmelisiniz.


final _formKey = GlobalKey();

void validateAndNext() {
  if (_formKey.currentState!.validate()) {
    _formKey.currentState!.save();
    // Bir sonraki adıma geçiş mantığı
  }
}

Kritik Güvenlik Uyarısı: Form verilerini sunucuya gönderirken mutlaka HTTPS protokolünü kullanın. Şifre gibi hassas verileri asla düz metin olarak saklamayın veya göndermeyin. İstemci tarafındaki validasyon sadece kullanıcı deneyimi içindir; ana güvenlik kontrolü her zaman sunucu tarafında (Backend) yapılmalıdır.

Adım 5: Veri Akışı ve Sunucuya Gönderim

Tüm adımlar tamamlandığında, RegistrationData nesnesini bir API isteği ile sunucuya göndermelisiniz. 2026 standartlarında dio kütüphanesi ile asenkron istekler yönetmek en verimli yoldur.


Future submitRegistration(RegistrationData data) async {
  final response = await Dio().post('https://api.uygulamaniz.com/register', data: {
    'name': data.fullName,
    'email': data.email,
    'password': data.password, // Sunucuda hashlenmelidir
  });
  
  if (response.statusCode == 200) {
    // Başarılı yönlendirme
  }
}

Yöntem Karşılaştırması

Yöntem Avantaj Dezavantaj
Flutter Stepper Widget Hızlı entegrasyon Özelleştirme kısıtlı
Custom PageView Tam kontrol, animasyon Daha fazla kod yükü
State Management (Bloc/Riverpod) Ölçeklenebilir, test edilebilir Öğrenme eğrisi yüksek

Sıkça Sorulan Sorular

Adımlar arasında veri kaybını nasıl önlerim?

Verileri StateNotifier veya ChangeNotifier gibi bir durum yöneticisinde tutarak, widget ağacının üst katmanlarına taşıyın. Böylece sayfa geçişlerinde veriler bellekte kalmaya devam eder.

Form validasyonu neden önemli?

Kullanıcı hatalarını azaltmak, veritabanına kirli veri girmesini engellemek ve kötü niyetli girdilerin (XSS, SQL Injection denemeleri) önüne geçmek için kritik öneme sahiptir.

Klavye açıldığında formun kayması nasıl engellenir?

Scaffold widget'ında resizeToAvoidBottomInset: true özelliğini kullanarak formun klavye üzerinde kaydırılabilir bir alana sahip olmasını sağlayabilirsiniz.

İleri düzey animasyonlar eklemeli miyim?

Evet, adımlar arası geçişte AnimatedSwitcher kullanarak kullanıcıya akıcı bir deneyim sunabilirsiniz. Ancak animasyonların performansı bozmamasına dikkat edin.

Veri güvenliğini nasıl sağlarım?

Verileri yerel cihazda (Local Storage) tutacaksanız mutlaka flutter_secure_storage kütüphanesini kullanarak şifreli bir şekilde saklayın.

Form Süreçlerinde Performans Optimizasyonu ve Bellek Yönetimi

Çok adımlı formlar, özellikle karmaşık widget ağaçları içerdiğinde performans darboğazlarına yol açabilir. Kullanıcı her adım değiştirdiğinde tüm formun yeniden oluşturulmasını (rebuild) engellemek, uygulamanızın akıcılığını korumak için kritiktir. RepaintBoundary kullanımı ve const anahtar kelimesinin stratejik yerleşimi, gereksiz boyama işlemlerini minimize eder.

Ayrıca, büyük formlarda her tuş vuruşunda (onChanged) state güncellemesi yapmak yerine, FocusNode kullanarak kullanıcının alandan çıkış yapmasını (onFocusChange) beklemek veya Debounce mekanizması uygulamak, işlemci yükünü ciddi oranda azaltır.

// Debounce mekanizması ile performanslı veri girişi
import 'dart:async';

class Debouncer {
  final int milliseconds;
  Timer? _timer;

  Debouncer({required this.milliseconds});

  void run(VoidCallback action) {
    _timer?.cancel();
    _timer = Timer(Duration(milliseconds: milliseconds), action);
  }
}

// Kullanımı:
final _debouncer = Debouncer(milliseconds: 500);

TextField(
  onChanged: (value) {
    _debouncer.run(() {
      // API çağrısı veya ağır validasyon burada tetiklenir
      updateFormState(value);
    });
  },
)

Form Testleri: Birim ve Entegrasyon Stratejileri

Çok adımlı formların en büyük riski, bir adımdaki değişikliğin diğer adımları bozmasıdır. Bu nedenle, formunuzu test ederken sadece arayüzü değil, veri akışını da doğrulamalısınız. flutter_test paketi ile her bir adımın state değişimini simüle etmek, "regression" hatalarını önler.

Test süreçlerinde izlemeniz gereken temel senaryolar şunlardır:

  • Geçersiz Veri Testi: Zorunlu alanlar boş bırakıldığında "İleri" butonunun pasif kalıp kalmadığı.
  • Adım Geçişi Testi: StateNotifier'ın doğru adım indeksini tutup tutmadığı.
  • Veri Tutarlılığı: 1. adımdan 2. adıma geçip tekrar 1. adıma dönüldüğünde girilen verilerin korunup korunmadığı.
testWidgets('Form adımları arası veri geçişi testi', (WidgetTester tester) async {
  await tester.pumpWidget(const MyApp());

  // İlk adıma veri gir
  await tester.enterText(find.byKey(const Key('name_field')), 'Test Kullanıcısı');
  await tester.tap(find.text('İleri'));
  await tester.pumpAndSettle();

  // İkinci adımdan geri dön
  await tester.tap(find.text('Geri'));
  await tester.pumpAndSettle();

  // Verinin hala orada olduğunu doğrula
  expect(find.text('Test Kullanıcısı'), findsOneWidget);
});

İleri Düzey Hata Ayıklama (Debugging) İpuçları

Form süreçlerinde oluşan "State" hatalarını ayıklamak için flutter_riverpod kullanıyorsanız Riverpod Inspector aracını mutlaka kullanın. Bu araç, hangi provider'ın hangi veriyi tuttuğunu canlı olarak izlemenize olanak tanır. Eğer formunuzda beklenmedik bir "null" hatası alıyorsanız, form modelinizin copyWith metodunu kontrol edin; genellikle eksik kopyalanan alanlar bu tür hataların ana kaynağıdır.

Pro İpucu: Formunuzun o anki JSON çıktısını bir "Debug" ekranında veya konsolda anlık olarak loglamak, sunucu tarafındaki hata ayıklama sürecinizi %50 hızlandıracaktır.

Sonuç

Flutter & mobil ile ileri düzey çoklu form adımlı kayıt sihirbazı geliştirmek, doğru mimari ile oldukça sürdürülebilir bir süreçtir. Bu rehberde öğrendiğiniz durum yönetimi, modüler widget yapısı ve validasyon teknikleri, profesyonel uygulamalarınızın temelini oluşturacaktır. Bir sonraki adım olarak, formunuza "Google ile Giriş" veya "Telefon Doğrulama" gibi ek özellikler entegre etmeyi deneyebilirsiniz.

Yasal Uyarı: Bu kod örnekleri eğitim amaçlıdır. Üretim ortamına almadan önce tüm API uç noktalarını, veri doğrulama mantıklarını ve güvenlik katmanlarını (şifreleme, token yönetimi) projenizin ihtiyaçlarına göre profesyonelce gözden geçirin.

Bu yazıya tepkinizi paylaşın:
Zeynep Kaya

Dijital içerik editörlüğü geçmişimle, adım adım rehberlerin en anlaşılır ve uygulanabilir şekilde kurgulanmasını sağlıyorum. Teknik detayları herkes için sadeleştirmeyi seviyorum.

Yorumlar (0)

Yorum Yaz