כמה מודלים: MultiProvider
חלק מהיחידה ניהול מצב במסלול ה-Flutter של Coddy. שיעור 15 מתוך 27.
כדאי להקצות לכל מודל תפקיד אחד: הניקוד במחלקה אחת, והחיים במחלקה אחרת. קל לקרוא מודלים קטנים, ווידג׳ט עוקב רק אחרי מה שהוא צריך. אפליקציה עם כמה מודלים זקוקה לכמה ספקים.
אפשר לקנן אותם, ספק אחד בתור הילד של הבא אחריו, אבל הקוד נדחק ימינה עם כל מודל. MultiProvider מקבל רשימה שטוחה במקום זאת:
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => Score()),
ChangeNotifierProvider(create: (context) => Lives()),
],
child: const MyApp(),
),
);לספקים שברשימה אין child משלהם: MultiProvider עורם אותם בשבילך ומציב את child מתחת לכולם. כל ווידג׳ט שמתחתיהם יכול לעקוב אחר כל אחד מהמודלים או לקרוא אותו, לפי הטיפוס שלו: context.watch<Lives>().
אתגר
קלדף המשחק עוקב אחר שני מודלים, Score ו־Lives, אבל main מספק רק את הניקוד, ולכן האפליקציה מציגה שגיאה.
- החליפו את הספק ב־
mainב־MultiProviderשמספק את שני המודלים.
נסו בעצמכם
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Score extends ChangeNotifier {
int _points = 0;
int get points => _points;
void hit() {
_points += 10;
notifyListeners();
}
}
class Lives extends ChangeNotifier {
int _left = 3;
int get left => _left;
void miss() {
if (_left > 0) {
_left--;
notifyListeners();
}
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Score(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: GamePage(),
);
}
}
class GamePage extends StatelessWidget {
const GamePage({super.key});
@override
Widget build(BuildContext context) {
final points = context.watch<Score>().points;
final lives = context.watch<Lives>().left;
return Scaffold(
appBar: AppBar(title: Text('Lives: $lives')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Points: $points', style: const TextStyle(fontSize: 40)),
const SizedBox(height: 16),
Row(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () => context.read<Score>().hit(),
child: const Text('Hit'),
),
const SizedBox(width: 16),
ElevatedButton(
onPressed: () => context.read<Lives>().miss(),
child: const Text('Miss'),
),
],
),
],
),
),
);
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה ניהול מצב
3Provider
Provider: שיתוף מודלקריאה ל-notifyListenersProvider: האזנה או קריאהProvider: Consumerשני מסכים, מודל אחדרשימת אובייקטים במודלכמה מודלים: MultiProviderתרגלו בעצמכם: קומפיילר Flutter אונליין