詳解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 堆棧中響應(yīng)。
/// 通過局部導航開啟一個彈窗
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)ⅲJ是不使用根節(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 使用Retrofit 以純二進制文件流上傳文件的操作代碼
文章介紹了如何在Android項目中使用Retrofit通過純二進制文件流上傳文件,包括單個文件流上傳和大文件分段上傳的方法,并詳細描述了需求協(xié)議、接口定義、RequestInterceptor的使用以及相關(guān)庫的調(diào)用,感興趣的朋友跟隨小編一起看看吧2024-11-11
android studio 新手入門教程(二)項目的導入教程圖解
這篇文章主要介紹了android studio 新手入門教程(二)項目的導入教程圖解,需要的朋友可以參考下2017-12-12
Android 6.0動態(tài)權(quán)限及跳轉(zhuǎn)GPS設(shè)置界面的方法
今天小編就為大家分享一篇Android 6.0動態(tài)權(quán)限及跳轉(zhuǎn)GPS設(shè)置界面的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07
Android播放assets文件里視頻文件相關(guān)問題分析
這篇文章主要介紹了Android播放assets文件里視頻文件相關(guān)問題分析,結(jié)合Android播放assets文件出現(xiàn)錯誤的實際問題給出了原因分析與解決方法參考,需要的朋友可以參考下2016-08-08
Android DatePicker和DatePickerDialog基本用法示例
這篇文章主要介紹了Android DatePicker和DatePickerDialog基本用法,實例分析了DatePicker和DatePickerDialog控件針對手機時間設(shè)置的相關(guān)技巧,需要的朋友可以參考下2016-06-06

