import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter/scheduler.dart'; /// NavBar 配置,由各页面在 build 中设置,AppShell 统一渲染 class NavBarConfig { final String title; final bool showBack; final bool showRight; final Widget? rightWidget; final VoidCallback? onBack; final IconData? leadingIcon; final bool hasFilter; final int filterVersion; const NavBarConfig({ required this.title, this.showBack = false, this.showRight = false, this.rightWidget, this.onBack, this.leadingIcon, this.hasFilter = false, this.filterVersion = 0, }); /// 根页面默认配置(无返回按钮) 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 && other.hasFilter == hasFilter && other.filterVersion == filterVersion; // 故意不比较 onBack / rightWidget / leadingIcon,避免每次 build 新闭包触发无限重建 @override int get hashCode => Object.hash(title, showBack, showRight, hasFilter, filterVersion); } /// NavBar 配置变更器,内部做相等判断避免无限重建 /// /// 通过 [Timer.run] 将状态更新推迟到事件循环下一个 tick, /// 避免子页面在 build 中更新 provider 时与 AppShell watch 冲突。 class NavBarConfigNotifier extends StateNotifier { NavBarConfigNotifier() : super(NavBarConfig.home); NavBarConfig? _pendingConfig; bool _scheduled = false; void update(NavBarConfig config) { if (state != config) { _pendingConfig = config; if (!_scheduled) { _scheduled = true; SchedulerBinding.instance.addPostFrameCallback((_) { _scheduled = false; if (mounted && _pendingConfig != null) { state = _pendingConfig!; _pendingConfig = null; } }); } } } } /// NavBar 配置的 Provider —— 各页面在 build 中更新,AppShell 统一消费 final navBarConfigProvider = StateNotifierProvider( (ref) => NavBarConfigNotifier(), );