| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  | // main_page.dart
 | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  | import 'package:flutter/material.dart'; | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  | import 'package:qhd_prevention/pages/badge_manager.dart'; | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  | import 'package:qhd_prevention/pages/home/scan_page.dart'; | 
					
						
							|  |  |  |  | import 'package:qhd_prevention/pages/my_appbar.dart'; | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  | import '../customWidget/nfc_test_page.dart'; | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  | import 'home/home_page.dart'; | 
					
						
							|  |  |  |  | import 'app/application_page.dart'; | 
					
						
							|  |  |  |  | import 'mine/mine_page.dart'; | 
					
						
							|  |  |  |  | import 'notif/notif_page.dart'; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class MainPage extends StatefulWidget { | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |   const MainPage({Key? key}) : super(key: key); | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   @override | 
					
						
							|  |  |  |  |   _MainPageState createState() => _MainPageState(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class _MainPageState extends State<MainPage> { | 
					
						
							|  |  |  |  |   int _currentIndex = 0; | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |   final GlobalKey<HomePageState> _homeKey = GlobalKey<HomePageState>(); | 
					
						
							|  |  |  |  |   late final List<Widget> _pages; | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   final List<String> _titles = ['首页', '应用中心', '通知公告', '我的']; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |   @override | 
					
						
							|  |  |  |  |   void initState() { | 
					
						
							|  |  |  |  |     super.initState(); | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |     _pages = <Widget>[ | 
					
						
							|  |  |  |  |       HomePage(key: _homeKey), | 
					
						
							|  |  |  |  |       const ApplicationPage(), | 
					
						
							|  |  |  |  |       const NotifPage(), | 
					
						
							|  |  |  |  |       const MinePage(), | 
					
						
							|  |  |  |  |     ]; | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |     // 监听 BadgeManager,当角标变化时 setState 刷新 UI
 | 
					
						
							|  |  |  |  |     BadgeManager().addListener(_onBadgeChanged); | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |   @override | 
					
						
							|  |  |  |  |   void dispose() { | 
					
						
							|  |  |  |  |     BadgeManager().removeListener(_onBadgeChanged); | 
					
						
							|  |  |  |  |     super.dispose(); | 
					
						
							|  |  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |   void _onBadgeChanged() { | 
					
						
							|  |  |  |  |     setState(() { | 
					
						
							|  |  |  |  |       // 只是为了重建,让 build 里拿到最新的 appCount / notifCount
 | 
					
						
							|  |  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |   void _onScanPressed() { | 
					
						
							|  |  |  |  |     final homeState = _homeKey.currentState; | 
					
						
							|  |  |  |  |     if (homeState != null) { | 
					
						
							|  |  |  |  |       try { | 
					
						
							|  |  |  |  |         // 尝试调用 startScan(),如果 HomePageState 中实现了这个方法就会执行
 | 
					
						
							|  |  |  |  |         (homeState as dynamic).startScan(); | 
					
						
							|  |  |  |  |         return; | 
					
						
							|  |  |  |  |       } catch (e) { | 
					
						
							|  |  |  |  |         // 如果调用失败则 fallback(打开 ScanPage)
 | 
					
						
							|  |  |  |  |         debugPrint('调用 HomePage.startScan 失败: $e'); | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |   } | 
					
						
							|  |  |  |  |   Widget _buildIconWithBadge({required Widget icon, required int badgeCount}) { | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |     if (badgeCount <= 0) return icon; | 
					
						
							|  |  |  |  |     return Stack( | 
					
						
							|  |  |  |  |       clipBehavior: Clip.none, | 
					
						
							|  |  |  |  |       children: [ | 
					
						
							|  |  |  |  |         icon, | 
					
						
							|  |  |  |  |         Positioned( | 
					
						
							|  |  |  |  |           right: -12, | 
					
						
							|  |  |  |  |           top: -4, | 
					
						
							|  |  |  |  |           child: Container( | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |             padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 1), | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |             decoration: BoxDecoration( | 
					
						
							|  |  |  |  |               color: Colors.red, | 
					
						
							|  |  |  |  |               borderRadius: BorderRadius.circular(8), | 
					
						
							|  |  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |             constraints: const BoxConstraints(minWidth: 16, minHeight: 16), | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |             child: Center( | 
					
						
							|  |  |  |  |               child: Text( | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |                 '$badgeCount', | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |                 style: const TextStyle( | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |                   color: Colors.white, | 
					
						
							|  |  |  |  |                   fontSize: 11, | 
					
						
							|  |  |  |  |                   height: 1, | 
					
						
							|  |  |  |  |                 ), | 
					
						
							|  |  |  |  |                 textAlign: TextAlign.center, | 
					
						
							|  |  |  |  |               ), | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |           ), | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |         ), | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |       ], | 
					
						
							|  |  |  |  |     ); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  |   @override | 
					
						
							|  |  |  |  |   Widget build(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |     final bm = BadgeManager(); | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  |     return Scaffold( | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |       appBar: | 
					
						
							|  |  |  |  |           _currentIndex == 1 | 
					
						
							|  |  |  |  |               ? null | 
					
						
							|  |  |  |  |               : MyAppbar( | 
					
						
							|  |  |  |  |                 title: _currentIndex == 0 ? "智守安全首页" : _titles[_currentIndex], | 
					
						
							|  |  |  |  |                 backgroundColor: Colors.blue, | 
					
						
							|  |  |  |  |                 isBack: false, | 
					
						
							|  |  |  |  |                 actions: [ | 
					
						
							|  |  |  |  |                   if (_currentIndex == 0) ...[ | 
					
						
							|  |  |  |  |                     IconButton( | 
					
						
							|  |  |  |  |                       onPressed: _onScanPressed, | 
					
						
							|  |  |  |  |                       // => Navigator.push(
 | 
					
						
							|  |  |  |  |                       //   context,
 | 
					
						
							|  |  |  |  |                       //   MaterialPageRoute(builder: (_) => ScanPage(totalList: [])),
 | 
					
						
							|  |  |  |  |                       // ),
 | 
					
						
							|  |  |  |  |                       icon: Image.asset( | 
					
						
							|  |  |  |  |                         "assets/images/scan.png", | 
					
						
							|  |  |  |  |                         width: 20, | 
					
						
							|  |  |  |  |                         height: 20, | 
					
						
							|  |  |  |  |                       ), | 
					
						
							|  |  |  |  |                     ), | 
					
						
							|  |  |  |  |                   ], | 
					
						
							|  |  |  |  |                 ], | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  |               ), | 
					
						
							|  |  |  |  |       body: _pages[_currentIndex], | 
					
						
							|  |  |  |  |       bottomNavigationBar: BottomNavigationBar( | 
					
						
							|  |  |  |  |         currentIndex: _currentIndex, | 
					
						
							|  |  |  |  |         type: BottomNavigationBarType.fixed, | 
					
						
							|  |  |  |  |         selectedItemColor: Colors.blue, | 
					
						
							|  |  |  |  |         unselectedItemColor: Colors.grey, | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |         onTap: (i) { | 
					
						
							|  |  |  |  |           setState(() => _currentIndex = i); | 
					
						
							|  |  |  |  |           // 切到“应用”或“通知”标签时,按需拉最新角标
 | 
					
						
							|  |  |  |  |           if (i == 1) BadgeManager().updateAppCount(); | 
					
						
							|  |  |  |  |           if (i == 2) BadgeManager().updateNotifCount(); | 
					
						
							|  |  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  |         items: [ | 
					
						
							|  |  |  |  |           BottomNavigationBarItem( | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |             icon: Image.asset( | 
					
						
							|  |  |  |  |               'assets/tabbar/basics.png', | 
					
						
							|  |  |  |  |               width: 24, | 
					
						
							|  |  |  |  |               height: 24, | 
					
						
							|  |  |  |  |             ), | 
					
						
							|  |  |  |  |             activeIcon: Image.asset( | 
					
						
							|  |  |  |  |               'assets/tabbar/basics_cur.png', | 
					
						
							|  |  |  |  |               width: 24, | 
					
						
							|  |  |  |  |               height: 24, | 
					
						
							|  |  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  |             label: '首页', | 
					
						
							|  |  |  |  |           ), | 
					
						
							|  |  |  |  |           BottomNavigationBarItem( | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |             icon: _buildIconWithBadge( | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |               icon: Image.asset( | 
					
						
							|  |  |  |  |                 'assets/tabbar/application.png', | 
					
						
							|  |  |  |  |                 width: 24, | 
					
						
							|  |  |  |  |                 height: 24, | 
					
						
							|  |  |  |  |               ), | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |               badgeCount: bm.appCount, | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |             activeIcon: _buildIconWithBadge( | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |               icon: Image.asset( | 
					
						
							|  |  |  |  |                 'assets/tabbar/application_cur.png', | 
					
						
							|  |  |  |  |                 width: 24, | 
					
						
							|  |  |  |  |                 height: 24, | 
					
						
							|  |  |  |  |               ), | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |               badgeCount: bm.appCount, | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  |             ), | 
					
						
							|  |  |  |  |             label: '应用', | 
					
						
							|  |  |  |  |           ), | 
					
						
							|  |  |  |  |           BottomNavigationBarItem( | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |             icon: _buildIconWithBadge( | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |               icon: Image.asset( | 
					
						
							|  |  |  |  |                 'assets/tabbar/works.png', | 
					
						
							|  |  |  |  |                 width: 24, | 
					
						
							|  |  |  |  |                 height: 24, | 
					
						
							|  |  |  |  |               ), | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |               badgeCount: bm.notifCount, | 
					
						
							| 
									
										
										
										
											2025-07-24 09:38:06 +08:00
										 |  |  |  |             ), | 
					
						
							|  |  |  |  |             activeIcon: _buildIconWithBadge( | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |               icon: Image.asset( | 
					
						
							|  |  |  |  |                 'assets/tabbar/works_cur.png', | 
					
						
							|  |  |  |  |                 width: 24, | 
					
						
							|  |  |  |  |                 height: 24, | 
					
						
							|  |  |  |  |               ), | 
					
						
							| 
									
										
										
										
											2025-08-07 17:33:16 +08:00
										 |  |  |  |               badgeCount: bm.notifCount, | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  |             ), | 
					
						
							|  |  |  |  |             label: '通知', | 
					
						
							|  |  |  |  |           ), | 
					
						
							|  |  |  |  |           BottomNavigationBarItem( | 
					
						
							|  |  |  |  |             icon: Image.asset('assets/tabbar/my.png', width: 24, height: 24), | 
					
						
							| 
									
										
										
										
											2025-09-01 17:25:55 +08:00
										 |  |  |  |             activeIcon: Image.asset( | 
					
						
							|  |  |  |  |               'assets/tabbar/my_cur.png', | 
					
						
							|  |  |  |  |               width: 24, | 
					
						
							|  |  |  |  |               height: 24, | 
					
						
							|  |  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  |             label: '我的', | 
					
						
							|  |  |  |  |           ), | 
					
						
							|  |  |  |  |         ], | 
					
						
							|  |  |  |  |       ), | 
					
						
							|  |  |  |  |     ); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } |