You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在全局单例值变化时触发Flutter Widget重建

全局单例值变更触发组件重建实现方案

第一步:改造全局单例,值更新时发送通知

你当前的单例直接暴露了cartSize属性,外部修改值时无法触发通知,需要将属性改为私有,通过setter拦截赋值操作,值更新后自动调用notifyListeners()发出变更信号:

library #######.globals;

import 'package:flutter/material.dart';

class GlobalSingleton extends ChangeNotifier {
  static final GlobalSingleton _instance = GlobalSingleton._internal();

  factory GlobalSingleton() {
    return _instance;
  }

  GlobalSingleton._internal() {
    _cartSize = 0;
  }

  // 私有变量,禁止外部直接修改
  late int _cartSize;

  // 提供getter供外部读取值
  int get cartSize => _cartSize;

  // 提供setter,赋值时自动发通知
  set cartSize(int value) {
    _cartSize = value;
    // 值变更后通知所有监听者
    notifyListeners();
  }
}

注意:后续所有修改购物车数量的操作,都必须通过GlobalSingleton().cartSize = 新值的方式赋值,才能触发通知,不要直接修改私有_cartSize变量。

第二步:在组件State中注册监听,收到通知触发重建

在购物车图标组件的状态类中,初始化时注册单例的变更监听,组件销毁时移除监听避免内存泄漏,收到通知后调用setState触发组件重建:

import 'package:######/globals/globals.dart';
import 'package:flutter/material.dart';

class BuildMarketplaceCartIcon extends StatefulWidget {
  const BuildMarketplaceCartIcon({Key? key}) : super(key: key);

  @override
  State<BuildMarketplaceCartIcon> createState() =>
      _BuildMarketplaceCartIconState();
}

class _BuildMarketplaceCartIconState extends State<BuildMarketplaceCartIcon> {
  CRUDMarketplaceCart localCartData = CRUDMarketplaceCart();
  // 持有全局单例引用
  final globalSingleton = GlobalSingleton();

  @override
  void initState() {
    super.initState();
    // 注册值变更监听
    globalSingleton.addListener(_onCartSizeChange);
  }

  @override
  void dispose() {
    // 组件销毁时移除监听,防止内存泄漏
    globalSingleton.removeListener(_onCartSizeChange);
    super.dispose();
  }

  // 监听回调:收到通知时触发重建
  void _onCartSizeChange() {
    if (mounted) {
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
      },
      child: Container(
        width: 72,
        padding: const EdgeInsets.symmetric(horizontal: 8),
        child: Stack(
          alignment: Alignment.center,
          children: [
            Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: const <Widget>[
                Icon(Icons.shopping_cart),
                Text(
                  'Cart',
                  overflow: TextOverflow.ellipsis,
                ),
              ],
            ),
            Positioned(
              top: 0,
              right: 0,
              child: Container(
                padding: const EdgeInsets.symmetric(
                  horizontal: 6,
                  vertical: 2,
                ),
                decoration: const BoxDecoration(
                  shape: BoxShape.circle,
                  color: Colors.white,
                ),
                alignment: Alignment.center,
                // 直接读取单例中的最新值
                child: Text(
                  '${globalSingleton.cartSize}',
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

使用说明

  • 任何位置需要修改购物车数量时,直接执行GlobalSingleton().cartSize = 新的数量即可,所有监听该值的组件会自动重建
  • 回调中执行setState前判断mounted是为了避免组件已经销毁时触发刷新报错

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 23:45:45