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,Görev
ZorKaranlık mod anahtarının tüm uygulamayı değiştirmesini sağlayın:
- En üste
final darkModeProvider = StateProvider((ref) => false);ekleyin. MyAppöğesini,themeModedeğeri sağlayıcıyı izleyen birConsumerWidgethâline getirin.SettingsScreenöğesini birConsumerWidgethâ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;
});
},
),
],
),
);
}
}
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
1State’i Üst Bileşene Taşıma
State’i Alt Bileşene AktarmaAlt Bileşene Bir Callback AktarmaDeğer Gönderen Callback’lerState’i Üst Bileşene Taşıma4Riverpod
Riverpod: ProviderScopeConsumerWidget ve ref.watchRiverpod: StateProviderRiverpod: NotifierDiğer Provider'ları İzleyen Provider'larState'in Nerede Tutulacağını SeçmekKendi başına pratik yap: Online Flutter derleyicisi