Flutter 使用Navigator进行局部跳转页面

老孟导读:Navigator组件使用的频率不是很高,但在一些场景下非常适用,比如局部表单多页填写、底部导航一直存在,每个tab各自导航场景。
Navigator 是管理路由的控件,通常情况下直接使用Navigator.of(context)的方法来跳转页面,之所以可以直接使用Navigator.of(context)是因为在WidgetsApp中使用了此控件,应用程序的根控件通常是MaterialApp,MaterialApp包含WidgetsApp,所以可以直接使用Navigator的相关属性。
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表示根据RouteSettings生成路由。
那么在什么情况下需要使用Navigator?在需要局部页面跳转的地方使用Navigator,如下面的场景:
头条客户端举报场景
头条客户端每一个新闻下面都有一个“叉号”,点击弹出相关信息,点击其中的局部,会在当前小窗户内跳转到举报页面,效果如下:

此场景就是使用Navigator的典型场景,点击举报,并不是全屏切换页面,而是仅仅在当前弹出的页面进行切换。
首页代码如下:
@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, '不感兴趣', '减少这类内容'),
Divider(),
_buildItem(Icons.access_alarm, '举报', '标题夸张,内容质量差 等',
showArrow: true, onPress: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return PageD();
}));
}),
Divider(),
_buildItem(Icons.perm_identity, '拉黑作者:新华网客户端', ''),
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页面跳转到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('举报'),
],
),
],
),
);
}
}

最终实现了局部跳转效果,只在中间区域变化,其他区域不变。
Tab内跳转
还有一个典型到应用场景就Tab内跳转,效果如下:

底部导航一直存在,每个tab都有自己的导航器。
首页代码如下:
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页面,点击其中一个跳转到相关详情页面,这里为了简便,只放了一个跳转按钮:
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控件不是特别常用,但在一些场景下非常适用。
交流
老孟Flutter博客地址(近200个控件用法):http://laomengit.com
欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:
![]() |
![]() |
Flutter 使用Navigator进行局部跳转页面的更多相关文章
- 如何不使用Navigator空间实现跳转页面?
//引入 Loading页面 主页面 登录页等页面组件 constructor(props) { super(props); this.state = { 登录状态: 等待检查 }; } compon ...
- 用jQuery.ajaxWebService请求WebMethod,Ajax处理实现局部刷新;及Jquery传参数,并跳转页面 用post传过长参数
首先在aspx.cs文件里建一个公开的静态方法,然后加上WebMethod属性. 如: [WebMethod] public static string GetUserName() { //. ...
- 微信小程序跳转页面
小程序页面有2种跳转,可以在wxml页面或者js中: 1,在wxml页面中: <navigator url="../index/index">跳转到新页面</na ...
- React Native之使用导航器跳转页面(react-navigation)
react-navigation是一个导航库,要使用react-navigation来实现跳转页面,首先得在项目中安装此库,由于Yarn是Facebook提供的替代npm的工具,可以加速node模块的 ...
- PhoneGap 白名单安全机制 navigator.app 加载外部页面返回以及退出介绍
一. Phonegap 白名单安全机制 Phonegap应用的页面大多存在于本地,但有时需要加载外部的Web页面到应用内置的浏览器 视图中已完成特定的应用功能,出于安全性考虑,PhoneGap 设立了 ...
- 【坑】前端使用ajax异步请求以后,springMvc拦截器跳转页面无效
文章目录 前言 `$.ajaxSetup( )` 后记 前言 本文着重解决前后端分离开发的页面调整问题. 笔者,在做一个需求,需要对访问网站,但是没有登录的用户进行拦截,将他们重定向到首页. 很简单的 ...
- 微信小程序携带参数跳转页面/获取页面栈
页面跳转携带参数(以传递两个参数为例) a.wxml 页面传递 1 <navigator url="/pages/b/b?id=1&sid='289'"> &l ...
- JS定时刷新页面及跳转页面
JS定时刷新页面及跳转页面 Javascript 返回上一页1. Javascript 返回上一页 history.go(-1), 返回两个页面: history.go(-2); 2. history ...
- Webform Session、Cookies传值,跳转页面方式
Session:每个独立的浏览器都会创建一个独立的Session,不是一台电脑一个Session 存放位置:服务器上 作用:只要里面有内容,那么这个网站中所有的C#端都能访问到这个变量 优点:安全,速 ...
随机推荐
- 用Swoole4 打造高并发的PHP协程Mysql连接池
码云代码仓库:https://gitee.com/tanjiajun/MysqlPool 代码仓库:https://github.com/asbectJ/swoole4.git 前言 在写这篇文章之前 ...
- spring bootweb综合开发的整理
1.json接口开发 当前开发中微服务的概念日渐深入人心,所以json数据交互可以带来的便利也不言而喻.在springboot中json数据的返回方式比较简单,只需要用@RestController注 ...
- POJ3169(差分约束:转载)
转载自mengxiang000000传送门 Layout Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10278 Ac ...
- Battery Charging Specification Revision 1.2 中文版本
Battery Charging Specification Revision 1.2 Li,Guanglei 2014.04.03 Rev0.1 转载请注明转自:http://blog.csdn.n ...
- 阿里面试居然跟我扯了半小时的CyclicBarrier
一个大腹便便,穿着格子衬衫的中年男子,拿着一个贴满Logo的Mac向我走来,看着稀少的头发,我心想着肯定是顶级技术大牛吧!但是我也是一个才华横溢的人,稳住我们能赢. 面试官:您好,先做一下自我介绍吧! ...
- 关于51单片机IO引脚的驱动能力与上拉电阻设计方案
转载自:http://bbs.dianyuan.com/article/20312-2 单片机的引脚,可以用程序来控制,输出高.低电平,这些可算是单片机的输出电压.但是,程序控制不了单片机的输出电流. ...
- JDBC02 加载JDBC驱动 建立连接
JDBC(Java Database Connection)为Java开发者使用数据库提供了统一的编程接口 sun公司由于不知道各个主流商用数据库的程序代码,因此无法自己写代码连接各个数据库,因此su ...
- python --整理数据结构(列表)
该整理来源于:https://www.runoob.com/python3/python3-data-structure.html 列表 python中列表是可变的,这是它区别于字符串和元组的最重要的 ...
- Java注解的定义和使用
注解也叫元数据,一种代码级别的说明.是jdk1.5后产生的一个特性,与类.接口.枚举同一个档次,他可以在包.类.字段.方法.局部变量.方法参数等的前面,用来对这些元素进行说明.注释: <!--m ...
- Spring初学笔记(二):Bean的注入
关于Bean的注入 在上一篇中,已经说到虽然注入确实可以降低类与类之间的耦合,但并没有解决调用者必须知道类的创建方法的问题,也可以说是没有实现调用者与类实现的解耦,我们也提到,为了实现两者的解耦,可以 ...

