import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; /// NavBar 配置,由各页面在 build 中设置,AppShell 统一渲染 class NavBarConfig { final String title; final bool showBack; final bool showRight; final Widget? rightWidget; final VoidCallback? onBack; final IconData? leadingIcon; const NavBarConfig({ required this.title, this.showBack = false, this.showRight = false, this.rightWidget, this.onBack, this.leadingIcon, }); /// 根页面默认配置(无返回按钮) static const home = NavBarConfig(title: 'TBOSS 工作台', showBack: false); static const messages = NavBarConfig(title: '消息', showBack: false); static const profile = NavBarConfig(title: '我的', showBack: false); /// 带返回按钮的页面快捷构造 factory NavBarConfig.withBack(String title, {VoidCallback? onBack}) { return NavBarConfig(title: title, showBack: true, onBack: onBack); } /// 带返回按钮 + 右侧按钮的页面快捷构造 factory NavBarConfig.withRight( String title, { required Widget rightWidget, VoidCallback? onBack, }) { return NavBarConfig( title: title, showBack: true, showRight: true, rightWidget: rightWidget, onBack: onBack, ); } @override bool operator ==(Object other) => other is NavBarConfig && other.title == title && other.showBack == showBack && other.showRight == showRight; // 故意不比较 onBack / rightWidget,避免每次 build 新闭包触发无限重建 @override int get hashCode => Object.hash(title, showBack, showRight); } /// NavBar 配置变更器,内部做相等判断避免无限重建 /// /// 通过 [Timer.run] 将状态更新推迟到事件循环下一个 tick, /// 避免子页面在 build 中更新 provider 时与 AppShell watch 冲突。 class NavBarConfigNotifier extends StateNotifier { NavBarConfigNotifier() : super(NavBarConfig.home); NavBarConfig? _pendingConfig; void update(NavBarConfig config) { if (state != config) { _pendingConfig = config; Timer.run(() { if (mounted && _pendingConfig != null && state != _pendingConfig) { state = _pendingConfig!; } _pendingConfig = null; }); } } } /// NavBar 配置的 Provider —— 各页面在 build 中更新,AppShell 统一消费 final navBarConfigProvider = StateNotifierProvider( (ref) => NavBarConfigNotifier(), );