问题: flutter优点之一就是可以模块化开发,但是模块与模块之间总是避免不了会出现界面互相跳转的问题,解决该问题可以有以下方式去解决:
1 使用export
各个模块之间export出需要给跳转的页面,同时需要相互依赖,这样导致模块与模块之间的耦合度过高。
2 在main.date中注册
flutter在MaterialApp存在routes,每个页面都可在此进行静态注册,注册完成后,都可使用注册的名称进行跳转,这样就解决了模块的耦合问题。但是这要进行跳转,界面与界面之间传递参数,就只能通过RoutSetting中的arguments进行传递,同时在传递到的页面也只能在该build的方法里面才能获取到参数。这样就存在若进入该页面需要使用该参数在initState中进行网络请求,那么这时该参数就无法获取到了。
3 封装路由模块解决
3.1 每个模块独自维护路由映射
3.2 在main.date中进行注册汇总
3.3 在MaterialApp的onGenerateRoute统一处理跳转
3.4需要使用的模块依赖app_route,并使用APPNavigator. pushNamed(...)即可实现跳转
实现代码如下
创建rout模块:app_route
APPRoute.data
class APPRoute {
static List<String> moduleNameList = new List<String>();
static Map<String, Function> modulePages = new Map<String, Function>();
static Map<String, Map<String, Function>> allPages = new Map<String, Map<String, Function>>();
static registerModule(String name){
moduleNameList.add(name);
}
static registerModulePage(String name, Map<String, Function> pages){
modulePages.addAll(pages);
allPages.addAll({name:pages});
}
static getAllRoute(){
return modulePages;
}
}
创建APPNavigator代码统一处理跳转回退方法
import 'package:flutter/cupertino.dart';
import 'package:paff_route/src/route_arguments.dart';
class APPNavigator {
static pushNamed(BuildContext context, String routeId, {params,popCallback}){
RouteArguments routeArgument = new RouteArguments();
routeArgument.params = params;
Navigator.pushNamed(context, routeId, arguments: routeArgument).then((data){
if(popCallback != null)
popCallback(data);
});
}
static pushReplacement(BuildContext context, String routeId, {params}){
RouteArguments routeArgument = new RouteArguments();
routeArgument.params = params;
Navigator.pushReplacementNamed(context, routeId, arguments: routeArgument);
}
static pushNamedAndRemoveUntil(BuildContext context, String routeId, {params}){
RouteArguments routeArgument = new RouteArguments();
routeArgument.params = params;
Navigator.of(context).pushNamedAndRemoveUntil(routeId,(Route<dynamic> route) => false, arguments: routeArgument);
}
static pushNamedAndRemoveUntilName(BuildContext context, String newRouteId, String oldRouteId,{params}){
RouteArguments routeArgument = new RouteArguments();
routeArgument.params = params;
Navigator.of(context).pushNamedAndRemoveUntil(newRouteId,ModalRoute.withName('/oldRouteId'), arguments: routeArgument);
}
static popUtil(BuildContext context, String routeId ){
Navigator.popUntil(context, ModalRoute.withName(routeId));
}
}
页面与页面之间的参数统一包装在RouteArguments中
class RouteArguments {
Map<String, dynamic> params;
}
其他模块依赖app_route并维护rout.date文件:
文件实现如下:
String moduleName = "Login";
Map<String, Function> route = <String, Function>{
'/LoginPage': (context, {arguments}) => VBLoginPage(arguments: arguments,),
};
class LoginRoute{
static register(){
AppRoute.registerModulePage(moduleName, route);
}
}
在main.date中初始化
initState -> LoginRoute.register();
最后在onGenerateRoute统一处理
onGenerateRoute: (RouteSettings settings) {
// 统一处理
final String name = settings.name;
final Function pageContentBuilder = AllRoute.getAllRoute()[name];
if (pageContentBuilder != null) {
final Route route = CupertinoPageRoute(
settings: RouteSettings(name: name),
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
}
},
flutter Navigator使用
1 回退:
Navigator.of(context).pop();或Navigator.pop(context);
2 添加:
Navigator.pushName(context,"name");
3 替换:
Navigator.pushReplacementNamed(context, "/screen4")
或
Navigator.popAndPushNamed(context, "/screen4");
pushReplacementNamed 与 popAndPushNamed 的区别在于: popAndPushNamed 能够执行 Screen2 弹出的动画与 Screen3 推进的动画而 pushReplacementNamed 仅显示 Screen3 推进的动画。
4 删除到指定页面
Navigator.of(context).pushNamedAndRemoveUntil('/screen4', (Route route) => false);
这里的 (Routeroute) => false 能够确保删除先前所有实例。
5 添加并删除部分页面
Navigator.of(context).pushNamedAndRemoveUntil('/screen4', ModalRoute.withName('/screen1'));
6 回退到指定页面
Navigator.popUntil(context, ModalRoute.withName('/Dashboard'));
flutter Navigator 跳转风格
使用方式: 调用自定义的路由方法
Navigator.of(context).push(CustomRoute(SecondPage()));
自定义的custom_router
import 'package:flutter/material.dart';
class CustomRoute extends PageRouteBuilder{
final Widget widget;
CustomRoute(this.widget)
:super(
// 设置过度时间
transitionDuration:Duration(seconds: 1),
// 构造器
pageBuilder:(
// 上下文和动画
BuildContext context,
Animation<double> animaton1,
Animation<double> animaton2,
){
return widget;
},
transitionsBuilder:(
BuildContext context,
Animation<double> animaton1,
Animation<double> animaton2,
Widget child,
){
// 需要什么效果把注释打开就行了
// 渐变效果
return FadeTransition(
// 从0开始到1
opacity: Tween(begin: 0.0,end: 1.0)
.animate(CurvedAnimation(
// 传入设置的动画
parent: animaton1,
// 设置效果,快进漫出 这里有很多内置的效果
curve: Curves.fastOutSlowIn,
)),
child: child,
);
// 缩放动画效果
// return ScaleTransition(
// scale: Tween(begin: 0.0,end: 1.0).animate(CurvedAnimation(
// parent: animaton1,
// curve: Curves.fastOutSlowIn
// )),
// child: child,
// );
// 旋转加缩放动画效果
// return RotationTransition(
// turns: Tween(begin: 0.0,end: 1.0)
// .animate(CurvedAnimation(
// parent: animaton1,
// curve: Curves.fastOutSlowIn,
// )),
// child: ScaleTransition(
// scale: Tween(begin: 0.0,end: 1.0)
// .animate(CurvedAnimation(
// parent: animaton1,
// curve: Curves.fastOutSlowIn
// )),
// child: child,
// ),
// );
// 左右滑动动画效果
// return SlideTransition(
// position: Tween<Offset>(
// // 设置滑动的 X , Y 轴
// begin: Offset(-1.0, 0.0),
// end: Offset(0.0,0.0)
// ).animate(CurvedAnimation(
// parent: animaton1,
// curve: Curves.fastOutSlowIn
// )),
// child: child,
// );
}
);
}