Flutter學(xué)習(xí)之Navigator的高級(jí)用法分享
簡(jiǎn)介
上篇文章我們講到了flutter中navigator的基本用法,我們可以使用它的push和pop方法來(lái)進(jìn)行Router之間的跳轉(zhuǎn)。
在flutter中一個(gè)Router就是一個(gè)widget,但是在Android中,一個(gè)Router就是Activity,在IOS中,一個(gè)Router是一個(gè)ViewController。
Router除了之前講過(guò)的push和pop方法之外,還有一些更加高級(jí)的用法,一起來(lái)看看吧。
named routes
雖然在flutter中navigator將routers以stack的形式進(jìn)行存儲(chǔ),能做的也只是push和pop操作,但是事實(shí)上Router是可以有名字的。
想想也是,如果Router沒(méi)有名字的話(huà),那么如何順利進(jìn)行跳轉(zhuǎn)呢?不可能每次都new一個(gè)Router出來(lái)吧。
navigator有一個(gè)方法叫做Navigator.pushNamed()用來(lái)將帶名字的Router壓入堆棧,我們來(lái)看下它的定義:
static Future<T?> pushNamed<T extends Object?>(
BuildContext context,
String routeName, {
Object? arguments,
}) {
return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
}這個(gè)方法需要傳入一個(gè)context和對(duì)應(yīng)的routeName,同時(shí)還可以帶一些參數(shù)。
那么怎么用這個(gè)方法呢?
首先我們需要定義一些Router,比如說(shuō)在創(chuàng)建MaterialApp的時(shí)候可以傳入routes參數(shù),來(lái)設(shè)置named Routers:
MaterialApp(
title: '這是named Routers',
initialRoute: '/firstPage',
routes: {
'/firstPage': (context) => const FirstPage(),
'/secondPage': (context) => const SecondPage(),
},
)上面的代碼中我們分別定了兩個(gè)routers,分別是firstPage和secondPage,他們分別對(duì)應(yīng)一個(gè)自定義的widget。
定義好Router之后,我們就可以向下面這樣使用了:
onPressed: () {
Navigator.pushNamed(context, '/secondPage');
}如果要返回第一個(gè)頁(yè)面的話(huà),那么可以調(diào)用Navigator.pop方法來(lái)實(shí)現(xiàn):
onPressed: () {
Navigator.pop(context);
}給named route傳參數(shù)
在上一節(jié)我們講到pushNamed的時(shí)候,還介紹了它還可以接收參數(shù)arguments。從定義上可以看到arguments的類(lèi)型是Object對(duì)象,也就是說(shuō)任何對(duì)象都可以作為named route的參數(shù)。
那么我們先定義一個(gè)對(duì)象如下:
class TestArguments {
final String name;
final String description;
TestArguments(this.name, this.description);
}接下來(lái)我們需要?jiǎng)?chuàng)建一個(gè)能夠接受這個(gè)參數(shù)的Routers。
因?yàn)樗械腞outers都是Widget,所以我們需要?jiǎng)?chuàng)建一個(gè)Widget,并在這個(gè)widget內(nèi)部接收傳入的參數(shù)。
在flutter中有兩種傳遞參數(shù)的方式,你可以使用ModalRoute.of(),也可以使用onGenerateRoute()。
我們先來(lái)看下ModalRoute.of的定義:
static ModalRoute<T>? of<T extends Object?>(BuildContext context) {
final _ModalScopeStatus? widget = context.dependOnInheritedWidgetOfExactType<_ModalScopeStatus>();
return widget?.route as ModalRoute<T>?;
}它接收一個(gè)context參數(shù),然后返回一個(gè)route對(duì)象。
具體的用法如下:
class FirstPage extends StatelessWidget {
const FirstPage({super.key});
static const routeName = '/firstPage';
@override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as TestArguments;
return Scaffold(
appBar: AppBar(
title: Text(args.name),
),
body: Center(
child: Text(args.description),
),
);
}
}除了使用ModalRoute之外,還可以在onGenerateRoute()方法中進(jìn)行參數(shù)傳遞。onGenerateRoute是在Route生成的時(shí)候觸發(fā)的:
MaterialApp(
onGenerateRoute: (settings) {
if (settings.name == FirstPage.routeName) {
final args = settings.arguments as TestArguments;
return MaterialPageRoute(
builder: (context) {
return TestArguments(
title: args.title,
message: args.message,
);
},
);
}
return null;
},
)onGenerateRoute接收一個(gè)settings對(duì)象,我們需要在settings對(duì)象中設(shè)置對(duì)應(yīng)的name和arguments屬性。所以我們需要這樣調(diào)用:
Navigator.pushNamed(
context,
FirstPage.routeName,
arguments: TestArguments(
'測(cè)試',
'這是一個(gè)named Route',
),
);從Screen返回值
有時(shí)候我們需要從一個(gè)Screen返回到之前的Screen,并且不是簡(jiǎn)單的返回,我們還希望知道前一個(gè)screen返回了什么結(jié)果,然后可以根據(jù)前一個(gè)screen返回的不同結(jié)果來(lái)進(jìn)行不同的處理。
這個(gè)時(shí)候就需要用到Navigator.pop的傳參功能了。
比如我們?cè)诘谝粋€(gè)頁(yè)面中點(diǎn)擊了按鈕,跳轉(zhuǎn)到第二個(gè)頁(yè)面:
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SecondScreen()),
);這里我們使用到了Navigator.push方法,并且返回了一個(gè)result的值。
我們可以使用這個(gè)值來(lái)進(jìn)行一些邏輯判斷。
那么這個(gè)result的值是哪里傳遞過(guò)來(lái)的呢?
沒(méi)錯(cuò),就是SecondScreen中的Navigator.pop方法:
Navigator.pop(context, 'Yes');
這里的'Yes'就會(huì)傳遞給result供我們進(jìn)行邏輯判斷。
向Screen傳值
有時(shí)候我們需要在頁(yè)面跳轉(zhuǎn)的過(guò)程中傳遞一些參數(shù),那么怎么才能實(shí)現(xiàn)Screen之間的參數(shù)傳遞呢?
因?yàn)樵趂lutter中所有的Routers都是Widget,所以我們可以在跳轉(zhuǎn)到新的頁(yè)面的時(shí)候直接將參數(shù)以構(gòu)造函數(shù)的方式傳遞給Routers Widget。
比如我們有下面的Screen Widget:
class NameScreen extends StatelessWidget {
const NameScreen({super.key, required this.name});
final String name;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('NameScreen'),
),
body:
...
;
}
}想要傳值給它,可以在onTap方法中這樣寫(xiě):
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NameScreen(name: 'what is your name?'),
),
);總結(jié)
以上就是Navigator的更加高級(jí)的用法,我們可以通過(guò)Navigator來(lái)進(jìn)行數(shù)據(jù)傳遞等操作,從而實(shí)現(xiàn)更加復(fù)雜的頁(yè)面功能。
到此這篇關(guān)于Flutter學(xué)習(xí)之Navigator的高級(jí)用法分享的文章就介紹到這了,更多相關(guān)Flutter Navigator內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android實(shí)現(xiàn)仿Windows7圖片預(yù)覽窗格效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)仿Windows7圖片預(yù)覽窗格效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Android 圖文詳解Binder進(jìn)程通信底層原理
Android系統(tǒng)中,多進(jìn)程間的通信都是依賴(lài)于底層Binder IPC機(jī)制,Binder機(jī)制是一種RPC方案。例如:當(dāng)進(jìn)程A中的Activity與進(jìn)程B中的Service通信時(shí),就使用了binder機(jī)制2021-10-10
Android控件RadioButton實(shí)現(xiàn)多選一功能
這篇文章主要為大家詳細(xì)介紹了Android控件RadioButton實(shí)現(xiàn)多選一功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Android內(nèi)核源碼 在Ubuntu上下載,編譯,安裝
本文主要介紹Android內(nèi)核源碼,想學(xué)習(xí)深入研究Android的朋友肯定要看看Android內(nèi)核知識(shí)的,這里對(duì)下載Android內(nèi)核源代碼的下載,安裝,編譯做了詳細(xì)的介紹,有興趣的小伙伴可以參考下2016-08-08
Android自定義控件之可拖動(dòng)控制的圓環(huán)控制條實(shí)例代碼
這篇文章主要介紹了Android自定義控件之可拖動(dòng)控制的圓環(huán)控制條實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04
Android自定義頂部導(dǎo)航欄控件實(shí)例代碼
這篇文章主要介紹了Android自定義頂部導(dǎo)航欄控件實(shí)例代碼,需要的朋友可以參考下2017-12-12

