Vários modelos: MultiProvider
Parte da seção Gerenciamento de estado do Journey de Flutter da Coddy. Lição 15 de 27.
Mantenha cada modelo focado em uma única coisa: a pontuação em uma classe, as vidas em outra. Modelos pequenos são fáceis de ler, e um widget observa apenas o que precisa. Um app com vários modelos precisa de vários provedores.
Você poderia aninhá-los, com um provedor como filho do próximo, mas o código vai se deslocando para a direita a cada modelo. MultiProvider recebe uma lista simples:
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => Score()),
ChangeNotifierProvider(create: (context) => Lives()),
],
child: const MyApp(),
),
);Os provedores da lista não têm seu próprio child: MultiProvider os empilha para você e coloca child abaixo de todos eles. Cada widget descendente pode observar ou ler qualquer um dos modelos, cada um pelo seu tipo: context.watch<Lives>().
Desafio
FácilA página do jogo observa dois modelos, Score e Lives, mas main fornece apenas a pontuação, então o aplicativo exibe um erro.
- Substitua o provider em
mainpor umMultiProviderque forneça os dois modelos.
Experimente você mesmo
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'),
),
],
),
],
),
),
);
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Gerenciamento de estado
Pratique por conta própria: Compilador de Flutter online