| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- 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;
- 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<NavBarConfig> {
- 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<NavBarConfigNotifier, NavBarConfig>(
- (ref) => NavBarConfigNotifier(),
- );
|