v7
This commit is contained in:
@@ -1,185 +1,105 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../pages/color/color_add_page.dart';
|
||||
import '../../../pages/color/color_detail_page.dart';
|
||||
import '../../../pages/color/color_page.dart';
|
||||
import '../../../pages/counter/counter_page.dart';
|
||||
import '../../../pages/user/user_page.dart';
|
||||
import '../../../pages/settings/settings_page.dart';
|
||||
import '../transition/fade_transition_page.dart';
|
||||
import 'iroute_config.dart';
|
||||
|
||||
class IRoute {
|
||||
typedef IRoutePageBuilder = Page? Function(
|
||||
BuildContext context,
|
||||
IRouteConfig data,
|
||||
);
|
||||
|
||||
typedef IRouteWidgetBuilder = Widget? Function(
|
||||
BuildContext context,
|
||||
IRouteConfig data,
|
||||
);
|
||||
|
||||
abstract class IRouteNode {
|
||||
final String path;
|
||||
final IRoutePageBuilder? builder;
|
||||
final List<IRoute> children;
|
||||
final List<IRouteNode> children;
|
||||
|
||||
const IRoute({
|
||||
const IRouteNode({
|
||||
required this.path,
|
||||
this.children = const [],
|
||||
this.builder,
|
||||
required this.children,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'IRoute{path: $path, children: $children}';
|
||||
Page? createPage(BuildContext context, IRouteConfig config);
|
||||
|
||||
List<IRouteNode> find(String input,) {
|
||||
return findNodes(this, Uri.parse(input), 0, '/', []);
|
||||
}
|
||||
|
||||
IRoute? match(String path) {
|
||||
return matchRoute(this, path);
|
||||
}
|
||||
|
||||
List<IRoute> find(String input){
|
||||
String fixInput = input.substring(1);
|
||||
List<IRoute> nodes = findNodes(this,fixInput,0,'/',[]);
|
||||
if(nodes.isNotEmpty&&nodes.last.path!=input){
|
||||
return [];
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
List<IRoute> findNodes(IRoute node,String input,int deep,String prefix,List<IRoute> result){
|
||||
String separator = '/';
|
||||
|
||||
List<String> parts = input.split(separator);
|
||||
if(deep>parts.length-1){
|
||||
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){
|
||||
List<IRoute> nodes = node.children.where((e) => e.path==prefix+target).toList();
|
||||
if (node.children.isNotEmpty) {
|
||||
target = prefix + target;
|
||||
List<IRouteNode> nodes = node.children.where((e) => e.path == target).toList();
|
||||
bool match = nodes.isNotEmpty;
|
||||
if(match){
|
||||
IRoute matched = nodes.first;
|
||||
if (match) {
|
||||
IRouteNode matched = nodes.first;
|
||||
result.add(matched);
|
||||
String nextPrefix = '${matched.path}$separator';
|
||||
findNodes(matched, input, ++deep,nextPrefix,result);
|
||||
String nextPrefix = '${matched.path}/';
|
||||
findNodes(matched, uri, ++deep, nextPrefix, result);
|
||||
}else{
|
||||
result.add(NotFindNode(path: target));
|
||||
return result;
|
||||
}
|
||||
}else{
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// List<IRoute> findNodes(IRoute node,String input,int deep,String prefix,List<IRoute> result){
|
||||
// String separator = '/';
|
||||
// List<String> parts = input.split(separator);
|
||||
// if(deep>parts.length-1){
|
||||
// return result;
|
||||
// }
|
||||
// String target = parts[deep];
|
||||
// if(node.children.isNotEmpty){
|
||||
// List<IRoute> nodes = node.children.where((e) => e.path==prefix+target).toList();
|
||||
// bool match = nodes.isNotEmpty;
|
||||
// if(match){
|
||||
// IRoute matched = nodes.first;
|
||||
// result.add(matched);
|
||||
// String nextPrefix = '${matched.path}$separator';
|
||||
// findNodes(matched, input, ++deep,nextPrefix,result);
|
||||
// }
|
||||
// }else{
|
||||
// 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;
|
||||
|
||||
IRoute? matchRoute(IRoute route, String path) {
|
||||
if (route.path == path) {
|
||||
return route;
|
||||
} else {
|
||||
if (route.children.isNotEmpty) {
|
||||
for (int i = 0; i < route.children.length; i++) {
|
||||
IRoute current = route.children[i];
|
||||
IRoute? target = matchRoute(current, path);
|
||||
if (target != null) {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
typedef IRoutePageBuilder = Page? Function(
|
||||
BuildContext context, IRouteData data);
|
||||
|
||||
class IRouteData {
|
||||
final Object? extra;
|
||||
final bool forResult;
|
||||
final Uri uri;
|
||||
final bool keepAlive;
|
||||
|
||||
IRouteData({
|
||||
this.extra,
|
||||
required this.uri,
|
||||
this.forResult = false,
|
||||
this.keepAlive = false,
|
||||
});
|
||||
class NotFindNode extends IRouteNode{
|
||||
NotFindNode({required super.path, super.children= const[]});
|
||||
|
||||
@override
|
||||
Page? createPage(BuildContext context, IRouteConfig config) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
IRoute root = IRoute(path: 'root', children: kDestinationsIRoutes);
|
||||
|
||||
List<IRoute> kDestinationsIRoutes = [
|
||||
IRoute(
|
||||
path: '/color',
|
||||
builder: (ctx, data) {
|
||||
return const FadeTransitionPage(
|
||||
key: ValueKey('/color'),
|
||||
child: ColorPage(),
|
||||
);
|
||||
},
|
||||
children: [
|
||||
IRoute(
|
||||
path: '/color/detail',
|
||||
builder: (ctx, data) {
|
||||
final Map<String, String> queryParams = data.uri.queryParameters;
|
||||
String? selectedColor = queryParams['color'];
|
||||
Color color = Colors.black;
|
||||
if (selectedColor != null) {
|
||||
color = Color(int.parse(selectedColor, radix: 16));
|
||||
} else if (data.extra is Color) {
|
||||
color = data.extra as Color;
|
||||
}
|
||||
return FadeTransitionPage(
|
||||
key: const ValueKey('/color/detail'),
|
||||
child: ColorDetailPage(color: color),
|
||||
);
|
||||
},
|
||||
),
|
||||
IRoute(
|
||||
path: '/color/add',
|
||||
builder: (ctx, data) {
|
||||
return const FadeTransitionPage(
|
||||
key: ValueKey('/color/add'),
|
||||
child: ColorAddPage(),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
IRoute(
|
||||
path: '/counter',
|
||||
builder: (ctx, data) {
|
||||
return const FadeTransitionPage(
|
||||
key: ValueKey('/counter'),
|
||||
child: CounterPage(),
|
||||
);
|
||||
}),
|
||||
IRoute(
|
||||
path: '/user',
|
||||
builder: (ctx, data) {
|
||||
return const FadeTransitionPage(
|
||||
key: ValueKey('/user'),
|
||||
child: UserPage(),
|
||||
);
|
||||
}),
|
||||
IRoute(
|
||||
path: '/settings',
|
||||
builder: (ctx, data) {
|
||||
return const FadeTransitionPage(
|
||||
key: ValueKey('/settings'),
|
||||
child: SettingPage(),
|
||||
);
|
||||
}),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user