Menu
CoddyTech

Shopping Cart: The Badge

Part of the State Management section of Coddy's Flutter journey. Lesson 23 of 27.

Shops show the cart as an icon with a small number on it, a badge. Flutter has a widget for it: Badge draws its label in a red bubble on the corner of its child:

IconButton(
  icon: Badge(
    label: Text('${cart.length}'),
    isLabelVisible: cart.isNotEmpty,
    child: const Icon(Icons.shopping_cart),
  ),
  onPressed: () {},
)

isLabelVisible hides the bubble when it is false. An empty cart shows the plain icon, which is calmer than a 0. cart.isNotEmpty is true when the list has at least one item.

The badge watches the same cartProvider the title did. Any widget can, wherever it sits.

challenge icon

Challenge

Easy

Move the count from the title to a badge:

  • The title goes back to Shop.
  • Add a cart IconButton to the top bar's actions, with Icons.shopping_cart inside a Badge that shows the number of products.
  • Hide the badge's number while the cart is empty.

The button does nothing yet; the cart screen comes next.

Try it yourself

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: Text('Shop (${cart.length})')),
      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 iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in State Management

Practice on your own: Online Flutter compiler