Search code examples
flutterflutter-appbar

Update Cart badge counter in AppBar from multiple widgets


I am using a Reusable AppBar Widget which has title and action buttons.

In app bar actions, there is favorites icon button and cart icon button with a badge showing the total items in cart : enter image description here

App Bar widget:

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

class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
  final BuildContext context;
  final String title;
  final bool showBackButton;
  final Widget widget;
  final bool showActions;

  CustomAppBar({
    @required this.context,
    @required this.title,
    this.showBackButton = true,
    this.widget,
    this.showActions = true,
  });

  @override
  Widget build(BuildContext context) {
    return AppBar(
      title: Text(title),
      leading: showBackButton
          ? new IconButton(
              icon: new Icon(
                Icons.arrow_back,
              ),
              onPressed: () {
                if (widget != null) {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => widget,
                    ),
                  );
                  return true;
                } else {
                  Navigator.pop(context);
                }
              },
            )
          : null,
      actions: !showActions ? null : <Widget>[
        IconButton(
          icon: const Icon(Icons.favorite_border),
          onPressed: () {
            Navigator.pushReplacement(
              context,
              MaterialPageRoute<void>(
                builder: (BuildContext context) {
                  return MainHome(
                    selectedIndex: 1,
                  );
                },
              ),
            );
          },
        ),
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 5),
          child: Badge(
            position: BadgePosition.topEnd(top: 3, end: 3),
            animationDuration: Duration(milliseconds: 300),
            animationType: BadgeAnimationType.slide,
            badgeColor: Colors.white,
            toAnimate: true,
            badgeContent: Text(
              '5',
              style: TextStyle(
                  fontSize: 8,
                  color: Theme.of(context).primaryColor,
                  fontWeight: FontWeight.bold),
            ),
            child: IconButton(
              icon: const Icon(Icons.shopping_cart_rounded),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute<void>(
                    builder: (BuildContext context) {
                      return MainHome(
                        selectedIndex: 2,
                      );
                    },
                  ),
                );
              },
            ),
          ),
        ),
      ],
    );
  }

  @override
  Size get preferredSize {
    return new Size.fromHeight(kToolbarHeight);
  }
}

The app bar is used in all screens but with different parameters. Products List Page Search Widget

I want to update the counter in app bar whenever user add to cart, update cart, remove from cart. This can happens from multiple pages: Products list page, product details page, shopping cart page, search suggestions widget. All of these pages have cart actions(add/update/delete).

I don't want to manage this counter in each page. I need a way to manage it in one place and be notified whenever cart updated in order to update badge

I searched a lot. Some uses GLobalKey to manage state but doesn't work in my case as the appbar widget is stateless cannot be stateful.


Solution

  • i suggest that you use any kind of providers like the provider package or riverpod , you need something called notifyListeners , to notify the cart badge every time you add a new item to your cart , otherwise you cart item in your case won't be updated except on widget rebuild ; like navigating and such .

    you can check riverpod and provider from pub.dev , make sure to fully understand the docs because it can be tricky !

    Hope this answer helps you !