שני מסכים, מודל אחד
חלק מהיחידה ניהול מצב במסלול ה-Flutter של Coddy. שיעור 13 מתוך 27.
נתונים שמשותפים לשני מסכים הם המקום שבו Provider משתלם. מסך ההגדרות משנה את השם, ומסך הבית מציג אותו, בלי ששני המסכים יעבירו דבר זה לזה.
המיקום של ספק הנתונים חשוב. MaterialApp מכיל Navigator, וכל מסך שדוחפים נכנס אליו לצד home, ולא לתוכו:
ChangeNotifierProvider <- above MaterialApp: every screen finds it
MaterialApp
Navigator
HomePage
SettingsScreen <- pushed next to HomePageספק נתונים שעוטף רק את HomePage מגיע רק אל HomePage. המסך שנדחף אינו נמצא מתחתיו, ולכן הוא לא יכול למצוא את המודל. הציבו את ספק הנתונים מעל MaterialApp, בתוך main, וכך כל המסכים ישתפו אותו.
אל תתקנו את השגיאה באמצעות ChangeNotifierProvider שני במסך האחר. כך נוצר מודל שני: השגיאה נעלמת, אבל המסכים כבר לא משתפים דבר.
אתגר
בינוניהקש על סמל גלגל השיניים, הקלד שם ולחץ על Save: האפליקציה מציגה שגיאה, כי הספק עוטף רק את HomePage.
- העבר את
ChangeNotifierProviderאל מחוץ ל־MyAppולתוךmain, כך שיעטוף אתMyApp.
לאחר מכן, שמירת Ada תציג במסך הבית את Hello, Ada!.
נסו בעצמכם
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'),
),
],
),
),
);
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה ניהול מצב
תרגלו בעצמכם: קומפיילר Flutter אונליין