Varios modelos: MultiProvider
Parte de la sección Gestión del estado del Journey de Flutter de Coddy. Lección 15 de 27.
Mantén cada modelo centrado en una sola cosa: la puntuación en una clase, las vidas en otra. Los modelos pequeños son fáciles de leer, y un widget solo observa lo que necesita. Una aplicación con varios modelos necesita varios proveedores.
Podrías anidarlos, con un proveedor como hijo del siguiente, pero el código se desplaza hacia la derecha con cada modelo. MultiProvider acepta una lista plana:
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => Score()),
ChangeNotifierProvider(create: (context) => Lives()),
],
child: const MyApp(),
),
);Los proveedores de la lista no tienen un child propio: MultiProvider los apila por ti y coloca child debajo de todos ellos. Todos los widgets descendientes pueden observar o leer cualquiera de los modelos, cada uno por su tipo: context.watch<Lives>().
Desafío
FácilLa página del juego observa dos modelos, Score y Lives, pero main solo proporciona la puntuación, por lo que la aplicación muestra un error.
- Reemplaza el proveedor en
mainpor unMultiProviderque proporcione ambos modelos.
Pruébalo tú mismo
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 lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Gestión del estado
Practica por tu cuenta: Compilador de Flutter online