Menu
CoddyTech

Deux écrans, un modèle

Fait partie de la section Gestion d’état du Journey Flutter de Coddy. Leçon 13 sur 27.

Le partage de données entre deux écrans est là que Provider devient utile. L’écran des paramètres modifie le nom, et l’écran d’accueil l’affiche, sans que les deux écrans aient à se transmettre quoi que ce soit.

L’emplacement du fournisseur est important. MaterialApp contient un Navigator, et chaque écran que vous ajoutez s’y retrouve à côté de home, et non à l’intérieur :

ChangeNotifierProvider        <- above MaterialApp: every screen finds it
  MaterialApp
    Navigator
      HomePage
      SettingsScreen          <- pushed next to HomePage

Un fournisseur enveloppant HomePage n’est accessible qu’à HomePage. L’écran ajouté n’est pas en dessous, il ne peut donc pas trouver le modèle. Placez le fournisseur au-dessus de MaterialApp, dans main, et tous les écrans le partageront.

Ne corrigez pas l’erreur en ajoutant un second ChangeNotifierProvider sur l’autre écran. Cela crée un second modèle : l’erreur disparaît, mais les écrans ne partagent plus rien.

challenge icon

Défi

Moyen

Appuie sur l’engrenage, saisis un nom et appuie sur Save : l’application affiche une erreur, car le fournisseur n’englobe que HomePage.

  • Déplace ChangeNotifierProvider hors de MyApp et place-le dans main, autour de MyApp.

Ensuite, enregistrer Ada affiche Hello, Ada! sur l’écran d’accueil.

Essayez vous-même

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'),
            ),
          ],
        ),
      ),
    );
  }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Gestion d’état

Entraînez-vous par vous-même : Compilateur Flutter en ligne