简介
flutter
本身提供了路由机制,作个人的小型项目,完全足够了。
但是如果你要作企业级开发,可能就会把入口文件变得臃肿不堪。可以使用企业级路由方案fluro
。
使用
- 修改
pubspec.yaml
文件,添加依赖fluro
# ...
dev_dependencies:
# ...
fluro: ^1.6.3
# ...
-
在
lib/
目录下新建router/
目录 -
在
lib/router/
目录下新建handler.dart
文件
import 'package:fluro/fluro.dart';
import 'package:weather/utils/logger.dart';
import 'package:weather/pages/splash_page.dart';
import 'package:weather/pages/weather_page.dart';
import 'package:weather/pages/cities_page.dart';
import 'package:weather/pages/settings_page.dart';
// not found页面
Handler notFoundHandler = Handler(handlerFunc: (_, params) {
Logger('RouterHandler:').log('Not Found Router');
});
// 根目录
Handler rootHandler = Handler(handlerFunc: (_, params) => SplashPage());
// 传参页面
Handler weatherHandler = Handler(handlerFunc: (_, params) {
String cityId = params['city_id']?.first;
return WeatherPage(city: cityId);
});
// 不传参页面
Handler settingHandler = Handler(handlerFunc: (_, params) => SettingsPage());
// 多个参数
Handler cityHandler = Handler(handlerFunc: (_, params) {
String provinceId = params['province_id']?.first;
String name = params['name']?.first;
return CityListPage(provinceId: provinceId, name: name);
});
- 在
lib/router/
目录下新建routers.dart
文件
import 'package:fluro/fluro.dart';
import 'package:weather/router/handler.dart';
// fluro 路由管理类
class Routers {
static const root = '/';
static const weather = '/weather';
static const cities = '/cities';
static const settings = '/settings';
static configureRouters(Router router) {
router.notFoundHandler = notFoundHandler;
router.define(root, handler: rootHandler);
router.define(weather, handler: weatherHandler);
router.define(settings, handler: settingHandler);
router.define(cities, handler: cityHandler);
}
// 对参数进行encode,解决参数中有特殊字符,影响fluro路由匹配
static Future navigateTo(BuildContext context, String path, { Map<String, dynamic> params, TransitionType transition = TransitionType.native }) {
String query = "";
if (params != null) {
int index = 0;
for (var key in params.keys) {
var value = Uri.encodeComponent(params[key]);
if (index == 0) {
query = "?";
} else {
query = query + "\&";
}
query += "$key=$value";
index++;
}
}
print('我是navigateTo传递的参数:$query');
path = path + query;
return router.navigateTo(context, path, transition:transition);
}
}
- 修改
lib/main.dart
文件,使用路由
// ...
import 'package:weather/router/routers.dart';
// ...
void main() {
WidgetsFlutterBinding.ensureInitialized();
// 注册 fluro router
Router router = Router();
Routers.configureRouters(router);
Routers.router = router;
runApp(WeatherApp());
}
class WeatherApp extends StatelessWidget {
const WeatherApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Weather App',
// onGenerateRoute 使用 fluro路由
onGenerateRoute: Routers.router.generator,
// ...
);
}
}
- 页面跳转
// 不传参
Routes.navigateTo(context, Routes.setting);
// 传参
Routes.navigateTo(context, Routes.weather, params: {
'city_id': 123
});
Router静态化
把Fluro
的Router
静态化
-
在
lib/
目录下新建common/
目录 -
在
lib/common/
目录下新建application.dart
文件
import 'package:fluro/fluro.dart';
class Application {
// 全局路由
static Router router;
}
- 修改
lib/main.dart
文件
// ...
import 'package:weather/router/routers.dart';
import 'package:weather/config/application.dart';
// ...
void main() {
WidgetsFlutterBinding.ensureInitialized();
// 注册 fluro router
Router router = Router();
Routers.configureRouters(router);
// 修改下面一句
Application.router = router;
runApp(WeatherApp());
}
class WeatherApp extends StatelessWidget {
const WeatherApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Weather App',
// 修改下面一句
onGenerateRoute: Application.router.generator,
// ...
);
}
}
- 页面跳转
// 不传参
Routes.navigateTo(context, '/settings');
// 传参
Routes.navigateTo(context, '/weather', params: {
'city_id': 123
});
分模块管理
- 在
lib/router/
目录下新建i_router.dart
文件
import 'package:fluro/fluro.dart';
abstract class IRouterProvider {
void initRouter(Router router);
}
- 在
lib/router/
目录下新建login_router.dart
文件(Login
模块的路由,其他模块路由类似)
import 'package:fluro/fluro.dart';
import 'i_router.dart';
import 'package:xxxx/ui/login/login_page.dart';
import 'package:xxxx/ui/login/register_page.dart';
import 'package:xxxx/ui/login/sms_page.dart';
import 'package:xxxx/ui/login/reset_password_page.dart';
import 'package:xxxx/ui/login/update_password_page.dart';
class LoginRouter implements IRouterProvider {
static String loginPage = '/login';
static String registerPage = '/login/register';
static String smsLoginPage = '/login/smsLogin';
static String resetPasswordPage = '/login/resetPassword';
static String updatePasswordPage = '/login/updatePassword';
@override
void initRouter(Router router) {
router.define(loginPage, handler: Handler(handlerFunc: (_, __) => LoginPage()));
router.define(registerPage, handler: Handler(handlerFunc: (_, __) => RegisterPage()));
router.define(smsLoginPage, handler: Handler(handlerFunc: (_, __) => SMSLoginPage()));
router.define(resetPasswordPage, handler: Handler(handlerFunc: (_, __) => ResetPasswordPage()));
router.define(updatePasswordPage, handler: Handler(handlerFunc: (_, __) => UpdatePasswordPage()));
}
}
- 修改
lib/router/routers.dart
文件
import 'package:fluro/fluro.dart';
import 'i_router.dart';
import 'login_router.dart';
import 'package:xxxx/ui/404.dart';
import 'package:xxxx/ui/home/home_page.dart';
import 'package:xxxx/ui/home/webview_page.dart';
// fluro 路由管理类
class Routers {
static String home = '/home';
static String webViewPage = '/webView';
static final Router router = Router();
static final List<IRouterProvider> _listRouter = [];
static void initRoutes() {
// 指定路由跳转错误返回页
router.notFoundHandler = Handler(
handlerFunc: (_, Map<String, List<String>> params) {
return NotFoundPage();
}
);
router.define(home,handler: Handler(
handlerFunc: (_, Map<String, List<String>> params) => HomePage()
));
router.define(webViewPage, handler: Handler(
handlerFunc: (_, Map<String, List<String>> params) {
final String title = params['title']?.first;
final String url = params['url']?.first;
return WebViewPage(title: title, url: url);
}
));
_listRouter.clear();
// 各自路由由各自模块管理,统一在此添加初始化
_listRouter.add(LoginRouter());
// 初始化路由
_listRouter.forEach((routerProvider) {
routerProvider.initRouter(router);
});
}
// 对参数进行encode,解决参数中有特殊字符,影响fluro路由匹配
static Future navigateTo(BuildContext context, String path, { Map<String, dynamic> params, TransitionType transition = TransitionType.native }) {
String query = "";
if (params != null) {
int index = 0;
for (var key in params.keys) {
var value = Uri.encodeComponent(params[key]);
if (index == 0) {
query = "?";
} else {
query = query + "\&";
}
query += "$key=$value";
index++;
}
}
print('我是navigateTo传递的参数:$query');
path = path + query;
return router.navigateTo(context, path, transition:transition);
}
}
封装页面跳转方法
- 在
lib/utils/
目录下新建navigator_util.dart
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
import 'package:xxxx/router/routers.dart';
class NavigatorUtil {
static void push(BuildContext context, String path, { bool replace = false, bool clearStack = false }) {
unfocus();
Routes.router.navigateTo(context, path, replace: replace, clearStack: clearStack, transition: TransitionType.native);
}
static void pushResult(BuildContext context, String path, Function(Object) function, { bool replace = false, bool clearStack = false }) {
unfocus();
Routes.router.navigateTo(context, path, replace: replace, clearStack: clearStack, transition: TransitionType.native).then((Object result) {
// 页面返回result为null
if (result == null) {
return;
}
function(result);
}).catchError((dynamic error) {
print('$error');
});
}
// 返回
static void goBack(BuildContext context) {
unfocus();
Navigator.pop(context);
}
// 带参数返回
static void goBackWithParams(BuildContext context, Object result) {
unfocus();
Navigator.pop<Object>(context, result);
}
// 跳到webview页
static void goWebViewPage(BuildContext context, String title, String url) {
// fluro 不支持传中文,需转换
push(context, '${Routes.webViewPage}?title=${Uri.encodeComponent(title)}&url=${Uri.encodeComponent(url)}');
}
static void unfocus() {
// 使用下面的方式,会触发不必要的build。
// FocusScope.of(context).unfocus();
// https://github.com/flutter/flutter/issues/47128#issuecomment-627551073
FocusManager.instance.primaryFocus?.unfocus();
}
}
- 代码中使用
import 'package:xxxx/utils/navigator_util.dart';
NavigatorUtil.push(context, LoginRouter.loginPage);
发表评论