import 'package:flutter/material.dart'; import '../iroute.dart'; import '../iroute_config.dart'; class NavigatorScope extends StatefulWidget { final IRouteNode node; final PopPageCallback onPopPage; final List configs; final IRoutePageBuilder notFindPageBuilder; const NavigatorScope({ super.key, required this.node, required this.onPopPage, required this.configs, required this.notFindPageBuilder, }); @override State createState() => _NavigatorScopeState(); } class _NavigatorScopeState extends State { @override Widget build(BuildContext context) { Widget content = Navigator( onPopPage: widget.onPopPage, pages: _buildPages(context, widget.configs), ); if(widget.node is CellIRoute){ content = (widget.node as CellIRoute).cellBuilder(context,widget.configs.last,content); } return HeroControllerScope( controller: MaterialApp.createMaterialHeroController(), child: content, ); } List _buildPages(BuildContext context, List configs) { IRouteConfig top = configs.last; List bottoms = configs.sublist(0, configs.length - 1).toList(); List pages = []; List topPages = _buildPageByPathFromTree(context, top); pages = _buildLivePageByPathList(context, bottoms, top, topPages); pages.addAll(topPages); return pages; } List _buildLivePageByPathList( BuildContext context, List paths, IRouteConfig curConfig, List curPages, ) { List pages = []; if (paths.isNotEmpty) { for (IRouteConfig path in paths) { if (path != curConfig) { pages.addAll(_buildPageByPathFromTree(context, path)); } } /// 去除和 curPages 中重复的界面 pages.removeWhere((page) => curPages.map((e) => e.key).contains(page.key)); } return pages; } List _buildPageByPathFromTree( BuildContext context, IRouteConfig config) { List result = []; List iRoutes = widget.node.find(config.path); if (iRoutes.isNotEmpty) { for (int i = 0; i < iRoutes.length; i++) { IRouteNode iroute = iRoutes[i]; IRouteConfig fixConfig = config; if(iroute.path!=config.uri.path){ fixConfig = IRouteConfig(uri: Uri.parse(iroute.path)); } Page? page; if (iroute is NotFindNode) { page = widget.notFindPageBuilder(context, config); } else if (iroute is CellIRoute) { Widget scope = NavigatorScope( node: iroute, onPopPage: widget.onPopPage, configs: widget.configs, notFindPageBuilder: widget.notFindPageBuilder, ); page = iroute.createCellPage(context, fixConfig, scope); } else { page = iroute.createPage(context, fixConfig); } if (page != null) { result.add(page); } if (iroute is CellIRoute) { break; } } } return result; } }