詳解flutter如何實(shí)現(xiàn)局部導(dǎo)航管理
引言
今天,小編給大家分享如何在 flutter 中實(shí)現(xiàn) ‘局部導(dǎo)航’。開(kāi)始之前我們先來(lái)統(tǒng)一一下關(guān)于 局部導(dǎo)航 的概念。
局部導(dǎo)航是什么?
我們?cè)?flutter 中使用 navigator 來(lái)管理 app 的頁(yè)面堆棧,主要包括 push、pop 這兩種操作。而當(dāng)我們UI設(shè)計(jì)劃分得更細(xì)致時(shí),可能遇到需要在某個(gè)獨(dú)立頁(yè)面里,單獨(dú)維護(hù)一套子級(jí)的堆棧管理。這就叫 局部導(dǎo)航管理。
局部控件內(nèi)單獨(dú)維護(hù)局部范圍內(nèi)的堆棧管理的形式有很多,例如:
- 形式一: 左側(cè)是菜單欄,右側(cè)是內(nèi)容塊,在內(nèi)容塊中單獨(dú)維護(hù)局部的頁(yè)面push、pop、操作。
- 形式二:dialog 彈窗中單獨(dú)維護(hù)布局堆棧管理。
那么下面,小編使用 dialog 的形式來(lái)分享實(shí)現(xiàn)過(guò)程。

實(shí)現(xiàn)步驟
第一步
創(chuàng)建工具類,用于局部導(dǎo)航管理,思想是:將需要單獨(dú)進(jìn)行堆棧管理的頁(yè)面使用新的子級(jí) navigator 進(jìn)行包裹,單獨(dú)維護(hù)一個(gè) navigator,做到每個(gè)堆棧容器實(shí)現(xiàn)內(nèi)部各自管理。
///工具類:用于局部導(dǎo)航管理
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 示例,實(shí)現(xiàn)一個(gè)單獨(dú)堆棧管理的彈窗內(nèi)部,對(duì)彈窗方法進(jìn)行封裝處理。
在 showDialog 時(shí)使用我們封裝的工具類 LocalNavigator 作為父節(jié)點(diǎn),對(duì)具體子頁(yè)面節(jié)點(diǎn)進(jìn)行包裹。
那么子頁(yè)面內(nèi)的堆棧操作(push 、pop、)都會(huì)在我們的 LocalNavigator 堆棧中響應(yīng)。
/// 通過(guò)局部導(dǎo)航開(kāi)啟一個(gè)彈窗
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('打開(kāi)彈窗'),
onPressed: () {
showLocalDialog<String?>(context, const _PageA())
.then(
(data) {
//接收來(lái)自 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) {
//接收來(lái)自 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)頁(yè)面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('我是來(lái)自pageB的數(shù)據(jù)');
},
child: const Text('返回pageA'),
),
const SizedBox(height: 20),
TextButton(
onPressed: () {
Navigator.of(context, rootNavigator: true).pop('我是來(lái)自pageC的數(shù)據(jù)');
},
child: const Text('關(guān)閉整個(gè)彈窗'),
),
],
),
),
);
}
}
技術(shù)點(diǎn)分析:
1. 局部 Navigator 管理重點(diǎn)
將 需要維護(hù)局部堆棧關(guān)系的子節(jié)點(diǎn) 進(jìn)行嵌套,使用自定義的工具類 LocalNavigator 作為父節(jié)點(diǎn)。
2. 返回上一級(jí)頁(yè)面,與關(guān)閉整個(gè)彈窗怎么區(qū)分?
關(guān)鍵點(diǎn)在于 Navigator.of(context) 中的 rootNavigator 可選入?yún)?,默認(rèn)是不使用根節(jié)點(diǎn)下的 navigator。
- 返回上一級(jí)頁(yè)面,使用當(dāng)前的堆棧進(jìn)行操作
Navigator.of(context).pop() - 關(guān)閉整個(gè)彈窗,意味著在根堆棧進(jìn)行 pop 操作
Navigator.of(context, rootNavigator: true).pop()
3. 如何接收頁(yè)面關(guān)閉時(shí)回傳的數(shù)據(jù)?
- 關(guān)閉時(shí)通過(guò) pop() 方法進(jìn)行數(shù)據(jù)回傳
Navigator.of(context).pop(data) - 接收回傳數(shù)據(jù),在打開(kāi)新堆棧的 push 方法中接收回返回值
Navigator.push<T?>(context, route).then((T){ })T 為返回值的泛型標(biāo)識(shí),注意在接收處理的地方需要對(duì)返回值進(jìn)行判空操作
Navigator.push<String?>(
context,
MaterialPageRoute(
builder: (context) => const _PageB(),
),
).then(
(data) {
if (data != null) {
//接收來(lái)自 pageB 的回調(diào)數(shù)據(jù)
Fluttertoast.showToast(msg: 'pageA 接收數(shù)據(jù):$data');
}
},
);以上就是詳解flutter如何實(shí)現(xiàn)局部導(dǎo)航管理的詳細(xì)內(nèi)容,更多關(guān)于flutter局部導(dǎo)航管理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Android?flutter?Dio鎖的巧妙實(shí)現(xiàn)方法示例
- flutter開(kāi)發(fā)技巧自定頁(yè)面指示器PageIndicator詳解
- Flutter開(kāi)發(fā)技巧RadialGradient中radius計(jì)算詳解
- flutter布局約束原理深入解析
- Flutter有狀態(tài)組件StatefulWidget生命周期詳解
- flutter中的JSON和序列化方法及使用詳解
- flutter中的網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)獲取詳解
- 替換so文件來(lái)動(dòng)態(tài)替換Flutter代碼實(shí)現(xiàn)詳解
相關(guān)文章
Android自定義View實(shí)現(xiàn)帶音效和震動(dòng)的SeekBar
這篇文章主要為大家詳細(xì)介紹了Android如何自定義View實(shí)一個(gè)帶音效和震動(dòng)的SeekBar,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03
Android?配合Mat工具監(jiān)聽(tīng)查找內(nèi)存泄漏的操作方法
這篇文章主要介紹了Android?配合Mat工具監(jiān)聽(tīng)查找內(nèi)存泄漏問(wèn)題,使用Android Studio Profiler查看內(nèi)存的操作,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
Android studio 使用Debugger問(wèn)題(代碼中含有ndk)
這篇文章主要介紹了Android studio 使用Debugger問(wèn)題(代碼中含有ndk),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-11-11
android導(dǎo)入第三方j(luò)ar包報(bào)錯(cuò) 如何正確導(dǎo)入jar包
怎樣在android平臺(tái)上使用第三方j(luò)ar包,為什么我在引入了,編譯時(shí)沒(méi)有錯(cuò)誤,運(yùn)行時(shí)就有錯(cuò)誤,報(bào)無(wú)法實(shí)例化錯(cuò)誤,請(qǐng)問(wèn)這是什么原因,本文給于解決方法,需要了解的朋友可以參考下2012-12-12
Android自定義View實(shí)現(xiàn)數(shù)字雨效果的全過(guò)程
小時(shí)候看時(shí)印象最深的就是數(shù)字雨了,導(dǎo)致我現(xiàn)在寫(xiě)代碼也要是黑屏,下面這篇文章主要給大家介紹了關(guān)于Android自定義View實(shí)現(xiàn)數(shù)字雨效果的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02
說(shuō)說(shuō)在Android如何使用服務(wù)(Service)的方法
這篇文章主要介紹了說(shuō)說(shuō)在Android如何使用服務(wù)(Service)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
Android TextView和ImageView簡(jiǎn)單說(shuō)明
Android TextView和ImageView簡(jiǎn)單說(shuō)明,需要的朋友可以參考一下2013-03-03

