Zwei Bildschirme, ein Modell
Teil des Abschnitts State Management der Flutter-Journey von Coddy. Lektion 13 von 27.
Bei Daten, die von zwei Bildschirmen gemeinsam genutzt werden, zahlt sich Provider aus. Der Einstellungsbildschirm ändert den Namen, und der Startbildschirm zeigt ihn an, ohne dass die beiden Bildschirme einander etwas übergeben müssen.
Es kommt darauf an, wo der Provider sitzt. MaterialApp enthält einen Navigator, und jeder Bildschirm, zu dem du navigierst, wird darin neben home eingefügt, nicht darin:
ChangeNotifierProvider <- above MaterialApp: every screen finds it
MaterialApp
Navigator
HomePage
SettingsScreen <- pushed next to HomePageEin Provider, der um HomePage herumgelegt wird, erreicht nur HomePage. Der hinzugefügte Bildschirm liegt nicht darunter und kann daher das Modell nicht finden. Platziere den Provider oberhalb von MaterialApp, in main, dann nutzen alle Bildschirme ihn gemeinsam.
Behebe den Fehler nicht mit einem zweiten ChangeNotifierProvider auf dem anderen Bildschirm. Dadurch entsteht ein zweites Modell: Der Fehler verschwindet, aber die Bildschirme nutzen nichts mehr gemeinsam.
Aufgabe
MittelTippe auf das Zahnradsymbol, gib einen Namen ein und drücke Save: Die App zeigt einen Fehler an, weil der Provider nur HomePage umschließt.
- Verschiebe den
ChangeNotifierProviderausMyAppheraus inmain, sodass erMyAppumschließt.
Wenn du dann Ada speicherst, wird auf der Startseite Hello, Ada! angezeigt.
Probier es selbst
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Profile extends ChangeNotifier {
String _name = 'Guest';
String get name => _name;
void rename(String newName) {
_name = newName;
notifyListeners();
}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: ChangeNotifierProvider(
create: (context) => Profile(),
child: const HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
final profile = context.watch<Profile>();
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
actions: [
IconButton(
icon: const Icon(Icons.settings),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SettingsScreen()),
);
},
),
],
),
body: Center(
child: Text('Hello, ${profile.name}!', style: const TextStyle(fontSize: 32)),
),
);
}
}
class SettingsScreen extends StatefulWidget {
const SettingsScreen({super.key});
@override
State<SettingsScreen> createState() => _SettingsScreenState();
}
class _SettingsScreenState extends State<SettingsScreen> {
final controller = TextEditingController();
@override
Widget build(BuildContext context) {
final profile = context.watch<Profile>();
return Scaffold(
appBar: AppBar(title: const Text('Settings')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Text('Signed in as ${profile.name}'),
const SizedBox(height: 16),
TextField(
controller: controller,
decoration: const InputDecoration(labelText: 'Your name'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
context.read<Profile>().rename(controller.text);
Navigator.pop(context);
},
child: const Text('Save'),
),
],
),
),
);
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in State Management
Übe selbstständig: Online-Flutter-Compiler