https://pub.dev/packages/fluro
https://github.com/lukepighetti/fluro
Fluro作为一款优秀的Flutter企业级路由框架,Fluro的使用比官方提供的路由框架要复杂一些,但是却非常适合中大型项目。
依赖
dependencies:fluro: ^1.7.8# 如果无法使用上面的方式添加Fluro依赖,还可以使用git的方式添加Fluro依赖dependencies:fluro:git: git://github.com/theyakka/fluro.git
导入
import 'package:fluro/fluro.dart';
使用
lib/main.dart
import "package:flutter/material.dart";import 'package:fluro/fluro.dart';import 'package:app1/routes/routes.dart';import 'package:app1/routes/application.dart';void main() {final router = FluroRouter(); //实例化路由Routes.configureRoutes(router); //导入路由Application.router = router; //路由静态化,以方便全局调用runApp(MyApp());}class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(initialRoute: '/', //默认路由onGenerateRoute: Application.router.generator,);}}
lib/routes/application.dart 路由静态化
import 'package:fluro/fluro.dart';class Application {static FluroRouter router;}
lib/routes/routes.dart 静态路由总体配置
import 'package:fluro/fluro.dart';import 'package:app1/routes/application.dart';import 'package:app1/routes/route_handles.dart';class Routes {static configureRoutes(FluroRouter router) {// 没有发现路由页面时处理router.notFoundHandler = Handler(handlerFunc: (context, params) {return Text('没有发现路由页面 $params');},);router.define('/', handler: appStartHandler); // 启动页(动画结束后,自动跳至首页)router.define('/home', handler: homeHandler); // 首页router.define('/test', handler: testHandler);router.define('/search', handler: searchHandler);router.define('/webview', handler: webviewHandler);}/** 对参数进行encode,解决参数中有特殊字符; Fluro会自动解码,不需再额外处理。* 示例 1: Routes.navigateTo(context, '/aa', params: {id: 1, title: '我是中文标题'});* 示例 2: Routes.navigateTo(context, '/aa', arguments: {id: 1, title: '我是中文标题'});** 注意:params方式、RouteSettings方式不能并存,传参时优先考虑使用params方式;* 如果params不满足使用,再用RouteSettings方式。例如首页"/",无法使用params传参,即可使用RouteSettings方式.*/static Future navigateTo(BuildContext context,String path, { //路由名称Map<String, dynamic> params, //search参数bool replace = false, //是否替换当前路由栈bool clearStack = false, //是否清空路由栈Duration transitionDuration = const Duration(milliseconds: 250), //动画周期RouteTransitionsBuilder transitionBuilder,TransitionType transition = TransitionType.material, //动画方式Map arguments, //RouteSettings 方式传参}) async {String query = "";if (params != null) {int index = 0;for (var key in params.keys) {if (params[key] != null) {var value = Uri.encodeComponent(params[key].toString());if (index == 0) {query = "?";} else {query = query + "\&";}query += "$key=$value";index++;}}}path = path + query;print('跳转的页面 => $path'); //我是navigateTo传递的参数:?id=11&title=%E6%9C%B1%E6%9C%9D%E9%98%B3return Application.router.navigateTo(context,path,replace: replace, // 是否替换当前页面clearStack: clearStack, // 是否情况页面存储栈信息transitionDuration: transitionDuration,transitionBuilder: transitionBuilder,transition: transition,routeSettings: arguments == null? null: RouteSettings(arguments: arguments),);}static pop(context, [params]) {Application.router.pop(context, params);}}/** TransitionType.inFromLeft //左侧进入* TransitionType.inFromRight //右侧进入* TransitionType.inFromBottom //底部进入 默认入场动画* TransitionType.native //无进入动画* TransitionType.nativeModal //同上* TransitionType.fadeIn //渐显动画* TransitionType.custom //自定义* TransitionType.material //感觉和上面几种一样 无特别动画效果* TransitionType.materialFullScreenDialog //感觉和上面几种一样 无特别动画效果* TransitionType.cupertino //右进右出* TransitionType.cupertinoFullScreenDialog //底部进 底部出 下个页面返回值变化*/
lib/routes/route_handles.dart 路由handler配置
最终2种传参方式(params、routeSettings)的参数,再通过 构造函数 方式 传给路由页面组件。
import 'package:flutter/material.dart';import 'package:fluro/fluro.dart';import 'package:app1/pages/app_start/index.dart';import 'package:app1/pages/home/index.dart';import 'package:app1/pages/search/index.dart';import 'package:app1/pages/web_view/index.dart';import 'package:app1/pages/test/index.dart';// app-启动页var appStartHandler = Handler(handlerFunc: (BuildContext context, Map<String, List<String>> params) {return AppStart();},);// 首页(params 方式传参)var homeHandler = Handler(handlerFunc: (context, params) {var index = params['index']?.first;return HomePage(index: index);},);// 搜索页(routeSettings 方式传参示例页面)var searchHandler = Handler(handlerFunc: (context, params) {var args = context.settings.arguments;return SearchPage(args);},);// webview页面var webviewHandler = Handler(handlerFunc: (context, params) {var url = params['url']?.first;var title = params['title']?.first;var showAppBar = params['showAppBar']?.first == 'true' ? true : false;return WebviewPage(url: url, title: title, showAppBar: showAppBar);},);// 测试demo页面var testHandler = Handler(handlerFunc: (context, params) {return TestPage();},);
lib/pages/home/index.dart 接收参数
class HomePage extends StatefulWidget {HomePage({key,this.index = '0',}) : super(key: key);final String index;@override_HomePageState createState() => _HomePageState();}...
lib/routes/route_push.dart 跳转
import 'package:flutter/material.dart';import 'package:app1/routes/routes.dart';import 'package:fluro/fluro.dart';class RoutePush {// 跳转到首页指定 tab RoutePush.home(context, index: 1);static home(context, {int index = 0, //底部导航索引}) {Routes.navigateTo(context,'/home',clearStack: true,params: {'index': index,},);}// 跳转到搜索页面(routeSettings方式传参示例页面) RoutePush.search(context, q: 'abc');static search(context, {String q = '', //搜索文本}) {Routes.navigateTo(context,'/search',arguments: {'q': q,},);}// 跳转webview页面 RoutePush.webview(context, url: 'https://www.baidu.com', title: '百度');static webview(BuildContext context, {@required String url, //网页链接String title = '', //页面标题bool showAppBar = true, //是否展示appBar}) {Routes.navigateTo(context,'/webview',params: {'url': url, 'title': title, 'showAppBar': showAppBar},);}}
传参
直接通过链接传参
handler配置
// webview页面var webviewHandler = Handler(handlerFunc: (context, params) {var url = params['url']?.first;var title = params['title']?.first;var showAppBar = params['showAppBar']?.first == 'true' ? true : false;return WebviewPage(url: url, title: title, showAppBar: showAppBar);},);
跳转
Application.router.navigateTo(context,'/webview?url=${Uri.encodeComponent(https://www.baidu.com)}&showAppBar=true',);
接收
class ApiDemoPage extends State<ApiDemoPage> {String title;String id;String isShare;ApiDemoPage({key, this.title, this.id, this.isShare}) : super(key: key);_getData() {print('${title} -- ${id} -- ${isShare}'); //zhu -- 11 -- null}//...}
通过 RouteSettings 传参
handler配置
var searchHandler = Handler(handlerFunc: (context, params) {var args = context.settings.arguments; //args {id: 11, title: zhu}return SearchPage(args);},);
跳转
Application.router.navigateTo(context,'/search',routeSettings: RouteSettings(arguments: {'id': 11,'title': 'zhu',},),);
search.dart 接收
class SearchPage extends StatelessWidget {final args;SearchPage(this.args);@overrideWidget build(BuildContext context) {print('args $args'); //args {id: 11, title: zhu}return null;}}
传参Map处理
传参前转为json字符串,接收时,再解码。
Application.router.pop() 返回
/// 返回上一个页面static pop() {// 全局 contextBuildContext myContext = navigatorKey.currentState.overlay.context;router.pop(myContext);}//这里设置了一个全局 context,如果没有设置,直接把 context 传入就行了。Application.router.pop(context);Application.router.pop(context, 1);
