Files
iroute/lib/v7/app/navigation/router/iroute.dart
toly 88cd6fb3b4 v7
2023-11-04 08:48:16 +08:00

106 lines
2.4 KiB
Dart

import 'package:flutter/material.dart';
import 'iroute_config.dart';
typedef IRoutePageBuilder = Page? Function(
BuildContext context,
IRouteConfig data,
);
typedef IRouteWidgetBuilder = Widget? Function(
BuildContext context,
IRouteConfig data,
);
abstract class IRouteNode {
final String path;
final List<IRouteNode> children;
const IRouteNode({
required this.path,
required this.children,
});
Page? createPage(BuildContext context, IRouteConfig config);
List<IRouteNode> find(String input,) {
return findNodes(this, Uri.parse(input), 0, '/', []);
}
List<IRouteNode> findNodes(
IRouteNode node,
Uri uri,
int deep,
String prefix,
List<IRouteNode> result,
) {
List<String> parts = uri.pathSegments;
if (deep > parts.length - 1) {
return result;
}
String target = parts[deep];
if (node.children.isNotEmpty) {
target = prefix + target;
List<IRouteNode> nodes = node.children.where((e) => e.path == target).toList();
bool match = nodes.isNotEmpty;
if (match) {
IRouteNode matched = nodes.first;
result.add(matched);
String nextPrefix = '${matched.path}/';
findNodes(matched, uri, ++deep, nextPrefix, result);
}else{
result.add(NotFindNode(path: target));
return result;
}
}
return result;
}
}
/// 优先调用 [pageBuilder] 构建 Page
/// 没有 [pageBuilder] 时, 使用 [widgetBuilder] 构建组件
/// 没有 [pageBuilder] 和 [widgetBuilder] 时, 使用 [widget] 构建组件
class IRoute extends IRouteNode {
final IRoutePageBuilder? pageBuilder;
final IRouteWidgetBuilder? widgetBuilder;
final Widget? widget;
final Map<String,dynamic>? mata;
const IRoute({
required super.path,
super.children = const [],
this.mata,
this.widget,
this.pageBuilder,
this.widgetBuilder,
});
@override
Page? createPage(BuildContext context, IRouteConfig config) {
if (pageBuilder != null) {
return pageBuilder!(context, config);
}
Widget? child;
if (widgetBuilder != null) {
child = widgetBuilder!(context, config);
}
child ??= widget;
if (child != null) {
return MaterialPage(child: child, key: config.pageKey);
}
return null;
}
}
class NotFindNode extends IRouteNode{
NotFindNode({required super.path, super.children= const[]});
@override
Page? createPage(BuildContext context, IRouteConfig config) {
return null;
}
}