詳解flutter如何實現(xiàn)局部導航管理
引言
今天,小編給大家分享如何在 flutter 中實現(xiàn) ‘局部導航’。開始之前我們先來統(tǒng)一一下關(guān)于 局部導航 的概念。
局部導航是什么?
我們在 flutter 中使用 navigator 來管理 app 的頁面堆棧,主要包括 push、pop 這兩種操作。而當我們UI設(shè)計劃分得更細致時,可能遇到需要在某個獨立頁面里,單獨維護一套子級的堆棧管理。這就叫 局部導航管理。
局部控件內(nèi)單獨維護局部范圍內(nèi)的堆棧管理的形式有很多,例如:
- 形式一: 左側(cè)是菜單欄,右側(cè)是內(nèi)容塊,在內(nèi)容塊中單獨維護局部的頁面push、pop、操作。
- 形式二:dialog 彈窗中單獨維護布局堆棧管理。
那么下面,小編使用 dialog 的形式來分享實現(xiàn)過程。
實現(xiàn)步驟
第一步
創(chuàng)建工具類,用于局部導航管理,思想是:將需要單獨進行堆棧管理的頁面使用新的子級 navigator 進行包裹,單獨維護一個 navigator,做到每個堆棧容器實現(xiàn)內(nèi)部各自管理。
///工具類:用于局部導航管理 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 示例,實現(xiàn)一個單獨堆棧管理的彈窗內(nèi)部,對彈窗方法進行封裝處理。
在 showDialog
時使用我們封裝的工具類 LocalNavigator
作為父節(jié)點,對具體子頁面節(jié)點進行包裹。
那么子頁面內(nèi)的堆棧操作(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 的回調(diào)數(shù)據(jù) if (data != null) { Fluttertoast.showToast(msg: 'mainPage 接收數(shù)據(jù):$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 的回調(diào)數(shù)據(jù) Fluttertoast.showToast(msg: 'pageA 接收數(shù)據(jù):$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('跳轉(zhuǎn)頁面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的數(shù)據(jù)'); }, child: const Text('返回pageA'), ), const SizedBox(height: 20), TextButton( onPressed: () { Navigator.of(context, rootNavigator: true).pop('我是來自pageC的數(shù)據(jù)'); }, child: const Text('關(guān)閉整個彈窗'), ), ], ), ), ); } }
技術(shù)點分析:
1. 局部 Navigator 管理重點
將 需要維護局部堆棧關(guān)系的子節(jié)點 進行嵌套,使用自定義的工具類 LocalNavigator
作為父節(jié)點。
2. 返回上一級頁面,與關(guān)閉整個彈窗怎么區(qū)分?
關(guān)鍵點在于 Navigator.of(context)
中的 rootNavigator
可選入?yún)?,默認是不使用根節(jié)點下的 navigator。
- 返回上一級頁面,使用當前的堆棧進行操作
Navigator.of(context).pop()
- 關(guān)閉整個彈窗,意味著在根堆棧進行 pop 操作
Navigator.of(context, rootNavigator: true).pop()
3. 如何接收頁面關(guān)閉時回傳的數(shù)據(jù)?
- 關(guān)閉時通過 pop() 方法進行數(shù)據(jù)回傳
Navigator.of(context).pop(data)
- 接收回傳數(shù)據(jù),在打開新堆棧的 push 方法中接收回返回值
Navigator.push<T?>(context, route).then((T){ })
T 為返回值的泛型標識,注意在接收處理的地方需要對返回值進行判空操作
Navigator.push<String?>( context, MaterialPageRoute( builder: (context) => const _PageB(), ), ).then( (data) { if (data != null) { //接收來自 pageB 的回調(diào)數(shù)據(jù) Fluttertoast.showToast(msg: 'pageA 接收數(shù)據(jù):$data'); } }, );
以上就是詳解flutter如何實現(xiàn)局部導航管理的詳細內(nèi)容,更多關(guān)于flutter局部導航管理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android自定義View實現(xiàn)帶音效和震動的SeekBar
這篇文章主要為大家詳細介紹了Android如何自定義View實一個帶音效和震動的SeekBar,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2024-03-03Android?配合Mat工具監(jiān)聽查找內(nèi)存泄漏的操作方法
這篇文章主要介紹了Android?配合Mat工具監(jiān)聽查找內(nèi)存泄漏問題,使用Android Studio Profiler查看內(nèi)存的操作,本文通過圖文實例相結(jié)合給大家介紹的非常詳細,需要的朋友可以參考下2022-05-05Android studio 使用Debugger問題(代碼中含有ndk)
這篇文章主要介紹了Android studio 使用Debugger問題(代碼中含有ndk),非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-11-11Android自定義View實現(xiàn)數(shù)字雨效果的全過程
小時候看時印象最深的就是數(shù)字雨了,導致我現(xiàn)在寫代碼也要是黑屏,下面這篇文章主要給大家介紹了關(guān)于Android自定義View實現(xiàn)數(shù)字雨效果的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-02-02Android TextView和ImageView簡單說明
Android TextView和ImageView簡單說明,需要的朋友可以參考一下2013-03-03