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

Flutter应用收到Firebase推送时如何让AppBar操作按钮更新状态显示红点

实现方案

1. 修复现有代码的变量引用问题

你现有代码中Consumer的builder回调已经返回了最新的bloc实例,但小红点判断逻辑用的是类成员_bloc,属于引用了旧实例导致状态更新不生效,直接替换为回调返回的bloc即可:

@override
Widget build(BuildContext context) {
return Consumer<EventsBloc>(builder: (ctx, bloc, child) {
  return Container(
    child: AppBar(
      automaticallyImplyLeading: false,
      leading: widget.backButtonIcon != null
          ? widget.backButtonIcon
          : GestureDetector(
                  child: Container(
                    child: CanaryIcons().menu,
                    padding: EdgeInsets.all(12),
                  ),
                  onTap: widget.onPressedLeading) ??
              Container(),
      title: titleEmpty
          ? Container(
              padding: EdgeInsets.only(bottom: 20, top: 20),
              child: widget.title.isEmpty
                  ? Text('Canary')
                  : Text(widget.title),
              alignment: Alignment.center,
            )
          : Text(widget.title, textAlign: TextAlign.center),
      actions: <Widget>[
        GestureDetector(
            child: Container(
                padding: EdgeInsets.all(15),
                child: Stack(children: [
                  Icon(Icons.notifications_outlined),
                  // 替换为回调返回的bloc实例,不要用旧的_bloc
                  bloc.hasNotifications ?? false
                      ? bloc.loadingState == ELoadingState.loading
                          ? Container()
                          : _redDot()
                      : Container()
                ])),
            onTap: widget.onPressedAction)
      ],
      bottom: widget.bottom,
      elevation: 2,
      brightness: _brightness(),
      backgroundColor: CanaryColors.darkBlue,
    ),
  );
});
}

2. 配置Firebase前台消息监听

在应用根节点的initState中添加前台推送监听,收到推送时直接更新EventsBloc的状态:

@override
void initState() {
  super.initState();
  // 监听前台收到的Firebase推送
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    final eventsBloc = Provider.of<EventsBloc>(context, listen: false);
    // 更新未读通知状态
    eventsBloc.updateUnreadStatus(true);
  });
}

3. 完善EventsBloc的状态通知逻辑

确保修改状态时调用了notifyListeners(),否则Provider不会触发UI刷新:

class EventsBloc extends ChangeNotifier {
  bool _hasNotifications = false;
  ELoadingState _loadingState = ELoadingState.idle;

  bool get hasNotifications => _hasNotifications;
  ELoadingState get loadingState => _loadingState;

  void updateUnreadStatus(bool hasUnread) {
    _hasNotifications = hasUnread;
    // 必须调用该方法通知所有监听组件刷新
    notifyListeners();
  }

  // 其余原有逻辑保持不变
}

可选优化:替换自定义红点为官方组件

可以直接用Flutter自带的Badge组件实现小红点,无需自己写_redDot方法,适配性更好:

Stack(
  children: [
    Icon(Icons.notifications_outlined),
    if (bloc.hasNotifications == true && bloc.loadingState != ELoadingState.loading)
      Positioned(
        right: 0,
        top: 0,
        child: Badge(
          backgroundColor: Colors.red,
          smallSize: 8,
        ),
      )
  ],
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 07:36:02