Flutter 使用Navigator進(jìn)行局部跳轉(zhuǎn)頁面的方法
Navigator組件使用的頻率不是很高,但在一些場景下非常適用,比如局部表單多頁填寫、底部導(dǎo)航一直存在,每個tab各自導(dǎo)航場景。
Navigator 是管理路由的控件,通常情況下直接使用Navigator.of(context)的方法來跳轉(zhuǎn)頁面,之所以可以直接使用Navigator.of(context)是因?yàn)樵?code>WidgetsApp中使用了此控件,應(yīng)用程序的根控件通常是MaterialApp,MaterialApp包含WidgetsApp,所以可以直接使用Navigator的相關(guān)屬性。
Navigator用法非常簡單,如下:
Navigator(
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
WidgetBuilder builder;
switch (settings.name) {
case 'home':
builder = (context) => PageA();
break;
case 'user':
builder = (context) => PageB();
break;
}
return MaterialPageRoute(builder: builder, settings: settings);
},
)
initialRoute表示初始化路由,onGenerateRoute表示根據(jù)RouteSettings生成路由。
那么在什么情況下需要使用Navigator?在需要局部頁面跳轉(zhuǎn)的地方使用Navigator,如下面的場景:
頭條客戶端舉報場景
頭條客戶端每一個新聞下面都有一個“叉號”,點(diǎn)擊彈出相關(guān)信息,點(diǎn)擊其中的局部,會在當(dāng)前小窗戶內(nèi)跳轉(zhuǎn)到舉報頁面,效果如下:

此場景就是使用Navigator的典型場景,點(diǎn)擊舉報,并不是全屏切換頁面,而是僅僅在當(dāng)前彈出的頁面進(jìn)行切換。
首頁代碼如下:
@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 350,
width: 300,
child: Navigator(
initialRoute: '/',
onGenerateRoute: (RouteSettings settins) {
WidgetBuilder builder;
switch (settins.name) {
case '/':
builder = (context) => PageC();
break;
}
return MaterialPageRoute(builder: builder);
},
),
),
);
}
Navigator的初始化路由為PageC頁面,PageC頁面代碼如下:
class PageC extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Card(
child: Column(
children: <Widget>[
_buildItem(Icons.clear, '不感興趣', '減少這類內(nèi)容'),
Divider(),
_buildItem(Icons.access_alarm, '舉報', '標(biāo)題夸張,內(nèi)容質(zhì)量差 等',
showArrow: true, onPress: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return PageD();
}));
}),
Divider(),
_buildItem(Icons.perm_identity, '拉黑作者:新華網(wǎng)客戶端', ''),
Divider(),
_buildItem(Icons.account_circle, '屏蔽', '軍事視頻、駕駛員等'),
],
),
),
);
}
_buildItem(IconData iconData, String title, String content,
{bool showArrow = false, Function onPress}) {
return Row(
children: <Widget>[
Icon(iconData),
SizedBox(
width: 20,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
title,
style: TextStyle(fontSize: 18),
),
Text(
content,
style: TextStyle(
color: Colors.black.withOpacity(.5), fontSize: 14),
)
],
),
),
!showArrow
? Container()
: IconButton(
icon: Icon(Icons.arrow_forward_ios),
iconSize: 16,
onPressed: onPress,
),
],
);
}
}
PageC頁面跳轉(zhuǎn)到PageD頁面,PageD頁面代碼如下:
class PageD extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 200,
width: 250,
color: Colors.grey.withOpacity(.5),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.of(context).pop();
},
),
Text('返回'),
SizedBox(
width: 30,
),
Text('舉報'),
],
),
],
),
);
}
}

最終實(shí)現(xiàn)了局部跳轉(zhuǎn)效果,只在中間區(qū)域變化,其他區(qū)域不變。
Tab內(nèi)跳轉(zhuǎn)
還有一個典型到應(yīng)用場景就Tab內(nèi)跳轉(zhuǎn),效果如下:

底部導(dǎo)航一直存在,每個tab都有自己的導(dǎo)航器。
首頁代碼如下:
class TabMain extends StatefulWidget {
@override
State<StatefulWidget> createState() => _TabMainState();
}
class _TabMainState extends State<TabMain> {
int _currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _currentIndex,
children: <Widget>[
TabNavigator(0),
TabNavigator(1),
TabNavigator(2),
],
),
bottomNavigationBar: BottomNavigationBar(
onTap: (int index) {
setState(() {
_currentIndex = index;
});
},
currentIndex: _currentIndex,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(title: Text('首頁'), icon: Icon(Icons.home)),
BottomNavigationBarItem(title: Text('書籍'), icon: Icon(Icons.book)),
BottomNavigationBarItem(
title: Text('我的'), icon: Icon(Icons.perm_identity)),
],
),
);
}
}
首頁定義了3個tab及切換效果。
定義TabNavigator:
class TabNavigator extends StatelessWidget {
TabNavigator(this.index);
final int index;
@override
Widget build(BuildContext context) {
return Navigator(
initialRoute: '/',
onGenerateRoute: (RouteSettings settins) {
WidgetBuilder builder;
switch (settins.name) {
case '/':
builder = (context) => ListPage(index);
break;
}
return MaterialPageRoute(builder: builder);
},
);
}
}
列表頁面,此頁面一般為List頁面,點(diǎn)擊其中一個跳轉(zhuǎn)到相關(guān)詳情頁面,這里為了簡便,只放了一個跳轉(zhuǎn)按鈕:
class ListPage extends StatelessWidget {
ListPage(this.index);
final int index;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: RaisedButton(
child: Text('$index'),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return DetailPage();
}));
},
),
),
);
}
}
詳情頁面
class DetailPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text('DetailPage'),
),
);
}
}
雖然Navigator控件不是特別常用,但在一些場景下非常適用。
總結(jié)
到此這篇關(guān)于Flutter 使用Navigator進(jìn)行局部跳轉(zhuǎn)頁面的文章就介紹到這了,更多相關(guān)Flutter 使用Navigator進(jìn)行局部跳轉(zhuǎn)頁面內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
刷新Activity中的scrollview示例(局部ui刷新)
代碼很簡單,但是很實(shí)用,適合在一個Activity中要刷新局部的UI,比如在掃描一維碼的時候,要把每次掃描的結(jié)果都顯示在界面上2014-01-01
android實(shí)現(xiàn)點(diǎn)擊圖片全屏展示效果
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)點(diǎn)擊圖片全屏展示效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-08-08
Android實(shí)現(xiàn)內(nèi)存中數(shù)據(jù)保存到sdcard的方法
這篇文章主要介紹了Android實(shí)現(xiàn)內(nèi)存中數(shù)據(jù)保存到sdcard的方法,涉及Android的文件讀寫與I/O操作相關(guān)技巧,需要的朋友可以參考下2016-01-01
詳解Android運(yùn)行時權(quán)限及APP適配方法
本篇文章給大家詳細(xì)分析了Android運(yùn)行時權(quán)限及APP適配方法,并把重要知識點(diǎn)做了說明,有需要的朋友參考下。2018-03-03
Android中Handler與Message的簡單實(shí)例
這篇文章主要介紹了Android中Handler與Message的簡單實(shí)例的相關(guān)資料,這里提供實(shí)例來說明線程Handler與message 的結(jié)合使用,需要的朋友可以參考下2017-08-08
Android 自定義View的構(gòu)造函數(shù)詳細(xì)介紹
這篇文章主要介紹了Android 自定義View的構(gòu)造函數(shù)詳細(xì)介紹的相關(guān)資料,這里對構(gòu)造函數(shù)進(jìn)行了對比按需使用,需要的朋友可以參考下2016-12-12
Android將應(yīng)用調(diào)試log信息保存在SD卡的方法
Android將應(yīng)用調(diào)試log信息保存在SD卡的方法大家都知道嗎,下面腳本之家小編給大家分享Android將應(yīng)用調(diào)試log信息保存在SD卡的方法,感興趣的朋友參考下2016-04-04
Android自定義View仿大眾點(diǎn)評星星評分控件
這篇文章主要為大家詳細(xì)介紹了Android自定義View仿大眾點(diǎn)評星星評分控件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-03-03
AndroidStudio 3.6 中 R.layout 找不到對應(yīng)的xml文件問題及解決方法
這篇文章主要介紹了AndroidStudio 3.6 中 R.layout 找不到對應(yīng)的xml文件問題,本文給出了解決方法對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
Android監(jiān)控和阻斷InputDispatching ANR的方法
如何在Java層實(shí)現(xiàn)異步監(jiān)控和阻斷InputDispatching ANR?我相信這是很多開發(fā)者都想要的功能,本篇,我們會通過“探索”兩種方案來實(shí)現(xiàn)在Java層監(jiān)控&阻斷的方法,需要的朋友可以參考下2024-04-04

