push<T> method
Future<void>
push<T>({
- required Widget page,
- ResultCallBack? onResult,
- String? name,
- Object? arguments,
- String? restorationId,
- bool maintainState = true,
- bool fullscreenDialog = false,
- bool allowSnapshotting = true,
- LaunchMode launchMode = LaunchMode.standard,
推出一个新页面到导航栈
Implementation
Future<void> push<T>(
{required Widget page,
ResultCallBack? onResult,
String? name,
Object? arguments,
String? restorationId,
bool maintainState = true,
bool fullscreenDialog = false,
bool allowSnapshotting = true,
LaunchMode launchMode = LaunchMode.standard}) async {
// 执行路由守卫检查(基于路由名称)
final from = RouteInformation(uri: Uri.parse(_location ?? '/'));
final to = RouteInformation(uri: Uri.parse(name ?? page.runtimeType.toString()));
final canNavigate = await _checkRouteGuards(from, to);
if (!canNavigate) {
return;
}
// 执行页面类型守卫检查
final fromPageType = _pages.isNotEmpty ? _pages.last.child.runtimeType : null;
final toPageType = page.runtimeType;
final canNavigateByType = await _checkPageTypeGuards(fromPageType, toPageType);
if (!canNavigateByType) {
return;
}
final routeSettings = RouteSettings(
name: name ?? page.runtimeType.toString(), arguments: arguments);
// 处理启动模式
switch (launchMode) {
case LaunchMode.singleTop:
// 如果栈顶已是该页面类型,则更新参数而不创建新实例(类似Android的onNewIntent)
if (_pages.isNotEmpty &&
_pages.last.child.runtimeType == page.runtimeType) {
// 更新栈顶页面的参数
final lastPage = _pages.removeLast();
_result.remove(lastPage.hashCode);
final updatedPage = MaterialPage(
child: page,
name: routeSettings.name,
arguments: routeSettings.arguments,
restorationId: restorationId,
maintainState: maintainState,
fullscreenDialog: fullscreenDialog,
allowSnapshotting: allowSnapshotting);
_pages.add(updatedPage);
_result[updatedPage.hashCode] = onResult;
notify();
return;
}
break;
case LaunchMode.singleInstance:
// 如果栈中已存在该页面,清除它上面的所有页面,并更新参数(类似Android的onNewIntent)
final existingIndex = _pages.indexWhere(
(element) => element.child.runtimeType == page.runtimeType);
if (existingIndex != -1) {
// 找到已存在的页面
// 1. 清除该页面上面的所有页面
final pagesToRemove = _pages.sublist(existingIndex);
for (var pageToRemove in pagesToRemove) {
_result.remove(pageToRemove.hashCode);
}
_pages.removeRange(existingIndex, _pages.length);
// 2. 用新参数重新创建该页面(类似onNewIntent)
final updatedPage = MaterialPage(
child: page,
name: routeSettings.name,
arguments: routeSettings.arguments,
restorationId: restorationId,
maintainState: maintainState,
fullscreenDialog: fullscreenDialog,
allowSnapshotting: allowSnapshotting);
_pages.add(updatedPage);
_result[updatedPage.hashCode] = onResult;
notify();
return;
}
// 如果不存在,继续执行后面的代码创建新实例
break;
case LaunchMode.standard:
// 标准模式,不做特殊处理
break;
}
final target = MaterialPage(
child: page,
name: routeSettings.name,
arguments: routeSettings.arguments,
restorationId: restorationId,
maintainState: maintainState,
fullscreenDialog: fullscreenDialog,
allowSnapshotting: allowSnapshotting);
_pages.add(target);
_result[target.hashCode] = onResult;
notify();
}