Dos pantallas, un modelo
Parte de la sección Gestión del estado del Journey de Flutter de Coddy. Lección 13 de 27.
Los datos compartidos por dos pantallas son donde Provider demuestra su utilidad. La pantalla de configuración cambia el nombre y la pantalla de inicio lo muestra, sin que las dos pantallas se pasen nada entre sí.
La ubicación del proveedor importa. MaterialApp contiene un Navigator, y cada pantalla que insertas se agrega a este junto a home, no dentro de él:
ChangeNotifierProvider <- above MaterialApp: every screen finds it
MaterialApp
Navigator
HomePage
SettingsScreen <- pushed next to HomePageUn proveedor que envuelve a HomePage solo llega a HomePage. La pantalla insertada no está debajo de él, así que no puede encontrar el modelo. Coloca el proveedor por encima de MaterialApp, en main, y todas las pantallas lo compartirán.
No corrijas el error con un segundo ChangeNotifierProvider en la otra pantalla. Eso crea un segundo modelo: el error desaparece, pero las pantallas ya no comparten nada.
Desafío
IntermedioToca el engranaje, escribe un nombre y pulsa Save: la aplicación muestra un error porque el proveedor solo envuelve HomePage.
- Mueve
ChangeNotifierProviderfuera deMyAppy ponlo enmain, alrededor deMyApp.
Después, al guardar Ada, se muestra Hello, Ada! en la pantalla de inicio.
Pruébalo tú mismo
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'),
),
],
),
),
);
}
}
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