Menu
CoddyTech

Panier d’achat : L’écran du panier

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

Un deuxième écran affiche le contenu du panier. C’est un ConsumerWidget qui observe le même cartProvider ; il n’a donc besoin d’aucun paramètre : affichez-le, et il lit lui-même le panier.

class CartScreen extends ConsumerWidget {
  const CartScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final cart = ref.watch(cartProvider);
    return Scaffold(
      appBar: AppBar(title: const Text('Your cart')),
      body: ...,
    );
  }
}

Vous vous souvenez du fournisseur qui entourait home et qui était introuvable depuis un écran affiché par-dessus ? Cela ne peut pas se produire ici : le ProviderScope englobe toute l’application, donc chaque écran accède à tous les fournisseurs.

Une liste vide sur un écran donne l’impression qu’il est cassé ; affichez donc une phrase à la place : cart.isEmpty ? ... : ... choisit entre les deux.

challenge icon

Défi

Moyen

Construis l’écran du panier :

  • Ajoute un CartScreen de type ConsumerWidget avec le titre Your cart.
  • Il affiche chaque produit du panier dans un ListTile, avec son nom et son prix dans trailing.
  • Lorsque le panier est vide, il affiche Your cart is empty à la place.
  • L’icône du panier dans la barre supérieure de la boutique ouvre cet écran.

Essayez vous-même

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class Product {
  const Product(this.name, this.price);

  final String name;
  final double price;
}

const products = [
  Product('Apple', 0.5),
  Product('Bread', 2.25),
  Product('Cheese', 4),
  Product('Milk', 1.2),
];

class Cart extends Notifier<List<Product>> {
  @override
  List<Product> build() => [];

  void add(Product product) {
    state = [...state, product];
  }
}

final cartProvider = NotifierProvider<Cart, List<Product>>(Cart.new);

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: ShopPage(),
    );
  }
}

class ShopPage extends ConsumerWidget {
  const ShopPage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final cart = ref.watch(cartProvider);
    return Scaffold(
      appBar: AppBar(
        title: const Text('Shop'),
        actions: [
          IconButton(
            icon: Badge(
              label: Text('${cart.length}'),
              isLabelVisible: cart.isNotEmpty,
              child: const Icon(Icons.shopping_cart),
            ),
            onPressed: () {},
          ),
        ],
      ),
      body: ListView(
        children: [
          for (final product in products)
            ListTile(
              title: Text(product.name),
              subtitle: Text('\$${product.price.toStringAsFixed(2)}'),
              trailing: IconButton(
                icon: const Icon(Icons.add_shopping_cart),
                onPressed: () {
                  ref.read(cartProvider.notifier).add(product);
                },
              ),
            ),
        ],
      ),
    );
  }
}
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