網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
1.Navigator使用簡(jiǎn)介
使用Flutter 的Navigator
導(dǎo)航器可以實(shí)現(xiàn)頁(yè)面的跳轉(zhuǎn),Navigator
的使用方法簡(jiǎn)單介紹一下:
頁(yè)面跳轉(zhuǎn):
Navigator.push<void>( context, MaterialPageRoute( builder: (BuildContext context) => const MyHomePage(), ), );
頁(yè)面跳轉(zhuǎn)的同時(shí)關(guān)閉當(dāng)前頁(yè)面(頁(yè)面替換):
Navigator.pushReplacement<void, void>( context, MaterialPageRoute( builder: (BuildContext context) => const MyHomePage(), ), );
頁(yè)面跳轉(zhuǎn)的同時(shí)關(guān)閉到之前的某一個(gè)頁(yè)面:
Navigator.pushAndRemoveUntil<void>( context, MaterialPageRoute( builder: (BuildContext context) => const MyHomePage(), ), (route) => false // ModalRoute.withName('/') );
也可以直接使用路由名稱進(jìn)行上面操作,例如跳轉(zhuǎn):Navigator.pushNamed(context, '/home');
路由名稱需要提前在MaterialApp
中定義好。
MaterialApp( title: 'Flutter Demo', home: MyHomePage(), routes: { "/page1": (context) => PageA(), "/page2": (context) => PageB(), }, );
接收參數(shù):var args = ModalRoute.of(context).settings.arguments;
頁(yè)面返回
Navigator.pop(context);
接收頁(yè)面的返回值:
Navigator.push<void>( context, MaterialPageRoute( builder: (BuildContext context) => const MyHomePage(), ), ).then((dynamic result) { // 頁(yè)面返回result });
必須同時(shí)配合Navigator.pop<dynamic>(context, result);
還有路由刪除removeRoute
,路由替換replace
等。
2.fluro
直接使用Navigator
的主要問(wèn)題是不易維護(hù)。如果某個(gè)頁(yè)面的傳參發(fā)生了變化,那么所有跳轉(zhuǎn)處都需要做修改。
所以我們可以使用現(xiàn)有封裝好的路由框架來(lái)替我們解決這些問(wèn)題。比如fluro。
1.配置
添加依賴至pubspec.yaml
:
dependencies: fluro: ^2.0.3
定義唯一一個(gè)FluroRouter
對(duì)象:
static final FluroRouter router = FluroRouter();
剩下的就是添加路由處理器Handler
,下面代碼舉例添加了兩個(gè)頁(yè)面:
class Routes { static String home = '/home'; static String webViewPage = '/webView'; static final List<IRouterProvider> _listRouter = []; static final FluroRouter router = FluroRouter(); static void initRoutes() { /// 指定路由跳轉(zhuǎn)錯(cuò)誤返回頁(yè) router.notFoundHandler = Handler( handlerFunc: (BuildContext? context, Map<String, List<String>> params) { debugPrint('未找到目標(biāo)頁(yè)'); return const NotFoundPage(); }); router.define(home, handler: Handler( handlerFunc: (BuildContext? context, Map<String, List<String>> params) => const Home())); // Routes.router.navigateTo(context, '${Routes.webViewPage}?title=標(biāo)題&url=地址'); router.define(webViewPage, handler: Handler(handlerFunc: (_, params) { /// 接收參數(shù) final String title = params['title']?.first ?? ''; final String url = params['url']?.first ?? ''; return WebViewPage(title: title, url: url); })); } }
配置fluro:
MaterialApp( onGenerateRoute: Routes.router.generator, );
初始化:
class MyApp extends StatelessWidget { MyApp() { Routes.initRoutes(); } ... }
2.使用方法
核心就一個(gè)方法navigateTo
,源碼如下:
Future navigateTo(BuildContext context, String path, {bool replace = false, bool clearStack = false, bool maintainState = true, bool rootNavigator = false, TransitionType? transition, Duration? transitionDuration, RouteTransitionsBuilder? transitionBuilder, RouteSettings? routeSettings}) { RouteMatch routeMatch = matchRoute(context, path, transitionType: transition, transitionsBuilder: transitionBuilder, transitionDuration: transitionDuration, maintainState: maintainState, routeSettings: routeSettings); Route<dynamic>? route = routeMatch.route; Completer completer = Completer(); Future future = completer.future; if (routeMatch.matchType == RouteMatchType.nonVisual) { completer.complete("Non visual route type."); } else { ///找不到時(shí)走`notFoundHandler` if (route == null && notFoundHandler != null) { route = _notFoundRoute(context, path, maintainState: maintainState); } if (route != null) { final navigator = Navigator.of(context, rootNavigator: rootNavigator); if (clearStack) { future = navigator.pushAndRemoveUntil(route, (check) => false); } else { future = replace ? navigator.pushReplacement(route) : navigator.push(route); } completer.complete(); } else { final error = "No registered route was found to handle '$path'."; print(error); completer.completeError(RouteNotFoundException(error, path)); } } return future; }
-
path
:路由名稱。 -
replace
:等同于pushReplacement
。 -
clearStack
:等同于pushAndRemoveUntil
。 -
transition
:頁(yè)面跳轉(zhuǎn)動(dòng)畫(huà),默認(rèn)native,平臺(tái)默認(rèn)動(dòng)畫(huà)。 -
transitionDuration
:動(dòng)畫(huà)時(shí)長(zhǎng)。 -
transitionBuilder
:自定義動(dòng)畫(huà)。 -
routeSettings
:用于傳遞數(shù)據(jù)。可使用context.settings.arguments
獲取。
具體的使用見(jiàn)項(xiàng)目routers目錄。
3.路由攔截
路由攔截可以實(shí)現(xiàn)權(quán)限控制。比如用戶沒(méi)有登錄,當(dāng)進(jìn)入某些需要登錄后才能顯示的頁(yè)面時(shí),可以攔截跳轉(zhuǎn)進(jìn)行判斷,引導(dǎo)用戶進(jìn)入登錄頁(yè)。
MaterialApp有 onGenerateRoute
方法可以在跳轉(zhuǎn)時(shí)進(jìn)行路由攔截。但是使用的fluro將這一屬性占用了,所以我們可以繼承 FluroRouter
類,重寫(xiě)navigateTo
方法實(shí)現(xiàn)。
class MyFluroRouter extends FluroRouter { List<String> _loginList; set loginList(value) => _loginList = value; @override Future navigateTo( BuildContext context, String path, { bool replace = false, bool clearStack = false, bool maintainState = true, bool rootNavigator = false, TransitionType transition, Duration transitionDuration, transitionBuilder, RouteSettings routeSettings, }) { String pathToNavigate = path; AppRouteMatch routeMatched = this.match(path); String routePathMatched = routeMatched?.route?.route; if (routePathMatched != null) { //如果頁(yè)面需要登錄,修改路由路徑到登錄頁(yè)面 if (_loginList != null && !_loginList.contains(routePathMatched)) { pathToNavigate = '/login‘; } } return super.navigateTo(context, pathToNavigate, replace: replace, clearStack: clearStack, maintainState: maintainState, rootNavigator: rootNavigator, transition: transition, transitionDuration: transitionDuration, transitionBuilder: transitionBuilder, routeSettings: routeSettings); } }
3.封裝
fluro工具類:
class NavigatorUtils { static void push(BuildContext context, String path, {bool replace = false, bool clearStack = false, Object? arguments}) { unfocus(); Routes.router.navigateTo(context, path, replace: replace, clearStack: clearStack, transition: TransitionType.native, routeSettings: RouteSettings( arguments: arguments, ), ); } static void pushResult(BuildContext context, String path, Function(Object) function, {bool replace = false, bool clearStack = false, Object? arguments}) { unfocus(); Routes.router.navigateTo(context, path, replace: replace, clearStack: clearStack, transition: TransitionType.native, routeSettings: RouteSettings( arguments: arguments, ), ).then((Object? result) { // 頁(yè)面返回result為null if (result == null) { return; } function(result); }).catchError((dynamic error) { debugPrint('$error'); }); } /// 返回 static void goBack(BuildContext context) { unfocus(); Navigator.pop(context); } /// 帶參數(shù)返回 static void goBackWithParams(BuildContext context, Object result) { unfocus(); Navigator.pop<Object>(context, result); } static void unfocus() { FocusManager.instance.primaryFocus?.unfocus(); } }
模塊管理:
import 'package:fluro/fluro.dart'; abstract class IRouterProvider { void initRouter(FluroRouter router); }
實(shí)現(xiàn)接口:
class LoginRouter implements IRouterProvider{ static String loginPage = '/login'; static String registerPage = '/login/register'; @override void initRouter(FluroRouter router) { router.define(loginPage, handler: Handler(handlerFunc: (_, __) => const LoginPage())); router.define(registerPage, handler: Handler(handlerFunc: (_, __) => const RegisterPage())); } }
各模塊初始化,放在Routes的initRoutes中:
/// 各自路由由各自模塊管理,統(tǒng)一在此添加初始化 _listRouter.add(LoginRouter()); ... /// 初始化路由 void initRouter(IRouterProvider routerProvider) { routerProvider.initRouter(router); } _listRouter.forEach(initRouter);
目前Flutter團(tuán)隊(duì)有維護(hù)一款路由框架go_router
(支持Navigator 2.0),但目前有部分功能缺失,比如不支持接收頁(yè)面的返回值,沒(méi)有pushAndRemoveUntil
方法。
期待后面功能的完善。但就目前來(lái)說(shuō),對(duì)于Android 和iOS平臺(tái)開(kāi)發(fā)來(lái)說(shuō)fluro的功能足夠使用了。
原文鏈接:https://blog.csdn.net/qq_17766199/article/details/127474553
相關(guān)推薦
- 2023-06-04 Pandas.DataFrame重置列的行名實(shí)現(xiàn)(set_index)_python
- 2022-02-15 Mybatis3 深入源碼 -- getMapper返回代理mapper源碼分析
- 2023-01-09 python自動(dòng)化測(cè)試中裝飾器@ddt與@data源碼深入解析_python
- 2022-09-25 2022react高頻面試題有哪些
- 2022-10-20 python文件數(shù)據(jù)分析治理提取_python
- 2023-05-29 Python?input輸入超時(shí)選擇默認(rèn)值自動(dòng)跳過(guò)問(wèn)題_python
- 2022-10-28 Go語(yǔ)言開(kāi)發(fā)保證并發(fā)安全實(shí)例詳解_Golang
- 2022-04-15 Python3實(shí)現(xiàn)自定義比較排序/運(yùn)算符_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支