網站首頁 編程語言 正文
引言
今天,小編給大家分享如何在 flutter 中實現 ‘局部導航’。開始之前我們先來統一一下關于 局部導航 的概念。
局部導航是什么?
我們在 flutter 中使用 navigator 來管理 app 的頁面堆棧,主要包括 push、pop 這兩種操作。而當我們UI設計劃分得更細致時,可能遇到需要在某個獨立頁面里,單獨維護一套子級的堆棧管理。這就叫 局部導航管理。
局部控件內單獨維護局部范圍內的堆棧管理的形式有很多,例如:
- 形式一: 左側是菜單欄,右側是內容塊,在內容塊中單獨維護局部的頁面push、pop、操作。
- 形式二:dialog 彈窗中單獨維護布局堆棧管理。
那么下面,小編使用 dialog 的形式來分享實現過程。
實現步驟
第一步
創建工具類,用于局部導航管理,思想是:將需要單獨進行堆棧管理的頁面使用新的子級 navigator 進行包裹,單獨維護一個 navigator,做到每個堆棧容器實現內部各自管理。
///工具類:用于局部導航管理 class LocalNavigator extends StatelessWidget { final Widget child; const LocalNavigator(this.child, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Navigator( initialRoute: '/', onGenerateRoute: (settings) { return MaterialPageRoute( settings: const RouteSettings(name: '/'), builder: (context) { return child; }, ); }, ); } }
第二步
如上 demo 示例,實現一個單獨堆棧管理的彈窗內部,對彈窗方法進行封裝處理。
在 showDialog
時使用我們封裝的工具類 LocalNavigator
作為父節點,對具體子頁面節點進行包裹。
那么子頁面內的堆棧操作(push 、pop、)都會在我們的 LocalNavigator 堆棧中響應。
/// 通過局部導航開啟一個彈窗 static Future<T?> showLocalDialog<T>( BuildContext context, Widget child, ) { return showDialog<T?>( context: context, builder: (context) { return Dialog( child: SizedBox( width: 200, height: 300, child: LocalNavigator(child), ), ); }, ); }
第三步
彈出 dialog,附上 demo 樣例的完整代碼
void main() { runApp(const Material( child: MyApp(), )); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('demo'), ), body: StatefulBuilder( builder: (context, setState) { return Center( child: TextButton( child: const Text('打開彈窗'), onPressed: () { showLocalDialog<String?>(context, const _PageA()) .then( (data) { //接收來自 dialog 的回調數據 if (data != null) { Fluttertoast.showToast(msg: 'mainPage 接收數據:$data'); } }, ); }, ), ); }, ), ), ); } } class _PageA extends StatelessWidget { const _PageA({Key? key}) : super(key: key); void jumpPageB(BuildContext context) { Navigator.push<String?>( context, MaterialPageRoute( builder: (context) => const _PageB(), ), ).then( (data) { if (data != null) { //接收來自 pageB 的回調數據 Fluttertoast.showToast(msg: 'pageA 接收數據:$data'); } }, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('PageA')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton( onPressed: () { jumpPageB(context); }, child: const Text('跳轉頁面B'), ), ], ), ), ); } } class _PageB extends StatelessWidget { const _PageB({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('PageB')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton( onPressed: () { Navigator.of(context).pop('我是來自pageB的數據'); }, child: const Text('返回pageA'), ), const SizedBox(height: 20), TextButton( onPressed: () { Navigator.of(context, rootNavigator: true).pop('我是來自pageC的數據'); }, child: const Text('關閉整個彈窗'), ), ], ), ), ); } }
技術點分析:
1. 局部 Navigator 管理重點
將 需要維護局部堆棧關系的子節點 進行嵌套,使用自定義的工具類 LocalNavigator
作為父節點。
2. 返回上一級頁面,與關閉整個彈窗怎么區分?
關鍵點在于 Navigator.of(context)
中的 rootNavigator
可選入參,默認是不使用根節點下的 navigator。
- 返回上一級頁面,使用當前的堆棧進行操作
Navigator.of(context).pop()
- 關閉整個彈窗,意味著在根堆棧進行 pop 操作
Navigator.of(context, rootNavigator: true).pop()
3. 如何接收頁面關閉時回傳的數據?
- 關閉時通過 pop() 方法進行數據回傳
Navigator.of(context).pop(data)
- 接收回傳數據,在打開新堆棧的 push 方法中接收回返回值
Navigator.push<T?>(context, route).then((T){ })
T 為返回值的泛型標識,注意在接收處理的地方需要對返回值進行判空操作
Navigator.push<String?>( context, MaterialPageRoute( builder: (context) => const _PageB(), ), ).then( (data) { if (data != null) { //接收來自 pageB 的回調數據 Fluttertoast.showToast(msg: 'pageA 接收數據:$data'); } }, );
原文鏈接:https://juejin.cn/post/7168662360230461454
相關推薦
- 2022-10-04 Python基礎之dict和set的使用詳解_python
- 2024-03-24 spring boot 3 + spring cloud sleuth 無法注入Tracer問題
- 2023-01-07 Android開發X?Y軸Board的繪制教程示例_Android
- 2022-04-05 debian:根據文件名稱,找到對應的包
- 2022-07-08 C#中的GDI+圖像編程詳解_C#教程
- 2023-10-17 uniapp中的image的src=“路徑”圖片不顯示
- 2022-08-04 Android解決所有雙擊優化的問題_Android
- 2022-03-29 python自動化之re模塊詳解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支