Menu
CoddyTech

Carrito de compras: La pantalla del carrito

Parte de la sección Gestión del estado del Journey de Flutter de Coddy. Lección 24 de 27.

Una segunda pantalla muestra qué hay en el carrito. Es un ConsumerWidget que observa el mismo cartProvider, así que no necesita que se le pase nada: ábrela y leerá el carrito por sí misma.

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: ...,
    );
  }
}

¿Recuerdas el proveedor que estaba alrededor de home y no se podía encontrar desde una pantalla abierta? Aquí eso no puede ocurrir: ProviderScope envuelve toda la aplicación, así que todas las pantallas pueden acceder a todos los proveedores.

Una lista vacía en una pantalla parece un error, así que muestra una frase en su lugar: cart.isEmpty ? ... : ... elige entre las dos opciones.

challenge icon

Desafío

Intermedio

Construye la pantalla del carrito:

  • Añade un CartScreen ConsumerWidget con el título Your cart.
  • Muestra cada producto del carrito en un ListTile con el nombre y el precio como trailing.
  • Cuando el carrito está vacío, muestra Your cart is empty en su lugar.
  • El icono del carrito en la barra superior de la tienda la abre.

Pruébalo tú mismo

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 iconPonte a prueba

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