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

如何借助Flutter Bloc Cubit在底部导航栏聊天项添加消息角标?

实现底部导航栏聊天项角标(Flutter Bloc/Cubit方案)

核心思路

通过全局的UnreadMessagesCubit统一管理未读消息总数,新消息到来时更新状态,底部导航栏组件监听该状态变化,动态渲染角标,保证聊天列表与底部导航的未读状态同步。

步骤实现

1. 创建未读消息管理Cubit

import 'package:flutter_bloc/flutter_bloc.dart';

class UnreadMessagesCubit extends Cubit<int> {
  UnreadMessagesCubit() : super(0);

  // 新增一条未读消息
  void incrementUnread() => emit(state + 1);
  // 重置未读数(进入聊天页时调用)
  void resetUnread() => emit(0);
  // 批量更新未读总数(比如从接口拉取初始数据)
  void updateUnreadCount(int count) => emit(count);
}

2. 在App顶层注入Cubit

确保根组件被BlocProvider包裹,让全局组件都能访问该Cubit:

void main() {
  runApp(
    BlocProvider(
      create: (context) => UnreadMessagesCubit(),
      child: const MyApp(),
    ),
  );
}

3. 底部导航栏监听状态渲染角标

用BlocBuilder监听UnreadMessagesCubit状态,给聊天导航项添加角标(这里用Flutter自带Badge,也可替换第三方Badge库):

int _selectedIndex = 0;
final List<Widget> _pages = [/* 对应5个页面的组件 */];

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: _pages[_selectedIndex],
    bottomNavigationBar: BlocBuilder<UnreadMessagesCubit, int>(
      builder: (context, unreadCount) {
        return BottomNavigationBar(
          items: [
            const BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
            const BottomNavigationBarItem(icon: Icon(Icons.search), label: '发现'),
            // 聊天导航项:根据未读数量显示角标
            BottomNavigationBarItem(
              icon: unreadCount > 0
                  ? Badge(
                      label: Text(unreadCount.toString()),
                      smallSize: 16,
                      child: const Icon(Icons.chat),
                    )
                  : const Icon(Icons.chat),
              label: '聊天',
            ),
            const BottomNavigationBarItem(icon: Icon(Icons.notifications), label: '通知'),
            const BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
          ],
          currentIndex: _selectedIndex,
          onTap: (index) {
            setState(() => _selectedIndex = index);
            // 切换到聊天页时重置未读数
            if (index == 2) {
              context.read<UnreadMessagesCubit>().resetUnread();
            }
          },
        );
      },
    ),
  );
}

4. 触发未读状态更新

  • 新消息到来时(如WebSocket推送、接口回调),调用Cubit方法更新:
// 示例:收到新消息时触发
void onNewMessageReceived() {
  context.read<UnreadMessagesCubit>().incrementUnread();
}
  • 若从本地存储/接口加载初始未读数据,可在Cubit初始化时处理:
UnreadMessagesCubit() : super(0) {
  _loadInitialUnreadCount();
}

Future<void> _loadInitialUnreadCount() async {
  // 模拟从本地或接口获取未读总数
  int count = await ChatRepository.getTotalUnreadCount();
  updateUnreadCount(count);
}

注意事项

  • 若用第三方Badge组件(如flutter_badge),需先添加依赖,用法与自带Badge类似
  • 多会话场景下,需在Cubit中汇总所有会话的未读数量,保证总数准确
  • 可自定义角标样式(大小、颜色、位置等)适配App风格

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 22:23:28