Menu
CoddyTech

State'in Nerede Tutulacağını Seçmek

Coddy'nin Flutter Journey'sinin Durum Yönetimi bölümünün bir parçası. Ders 21 / 27.

Ayarlar ekranındaki koyu mod anahtarı hareket ediyor, ancak hiçbir şey kararmıyor. Değerini setState ile koruyor ve onu yalnızca anahtar görebiliyor. Tema, çok uzakta, MyApp içinde ayarlanıyor. Bu değer tüm uygulamaya ait.

Bir uygulamadaki her değerin bir yuvaya ihtiyacı vardır. Onu kimin kullandığını sor:

  • Tek bir widget (bir alanın metni, açık bir panel, sekme dizini): o widget'ta setState.
  • Birbirine yakın birkaç widget (bir düğme ve yanındaki etiket): değeri üst öğeye taşı ve aşağıya aktar.
  • Birçok widget veya birkaç ekran (kullanıcı, sepet, ayarlar): Provider veya Riverpod ile paylaşılan bir model.

Provider mı, Riverpod mu? İkisi de işini görür. Provider biraz daha basittir ve modelleri widget ağacına yerleştirir; bunlara context üzerinden erişilir. Riverpod, sağlayıcıları ağacın dışında tutar; böylece bir değer için context gerekmez ve sağlayıcılar birbirlerini izleyebilir. Bir uygulama için birini seç ve her yerde onu kullan.

Burada bir StateProvider uygundur: bir bool; temayı seçmek için MyApp tarafından okunur ve anahtar tarafından değiştirilir:

final darkModeProvider = StateProvider((ref) => false);

// MyApp içinde, artık bir ConsumerWidget:
themeMode: ref.watch(darkModeProvider) ? ThemeMode.dark : ThemeMode.light,
challenge icon

Görev

Zor

Karanlık mod anahtarının tüm uygulamayı değiştirmesini sağlayın:

  • En üste final darkModeProvider = StateProvider((ref) => false); ekleyin.
  • MyApp öğesini, themeMode değeri sağlayıcıyı izleyen bir ConsumerWidget hâline getirin.
  • SettingsScreen öğesini bir ConsumerWidget hâline getirin: anahtar, sağlayıcının değerini gösterir ve değiştirildiğinde bu değeri ayarlar.

Kendin dene

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

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      themeMode: ThemeMode.light,
      home: const HomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Notes'),
        actions: [
          IconButton(
            icon: const Icon(Icons.settings),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => const SettingsScreen()),
              );
            },
          ),
        ],
      ),
      body: const Center(child: Text('No notes yet')),
    );
  }
}

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

  @override
  State<SettingsScreen> createState() => _SettingsScreenState();
}

class _SettingsScreenState extends State<SettingsScreen> {
  bool dark = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Settings')),
      body: ListView(
        children: [
          SwitchListTile(
            title: const Text('Dark mode'),
            value: dark,
            onChanged: (value) {
              setState(() {
                dark = value;
              });
            },
          ),
        ],
      ),
    );
  }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Durum Yönetimi bölümündeki tüm dersler

Kendi başına pratik yap: Online Flutter derleyicisi