本文主要是介绍flutter之从零开始搭建(二)之 Navigator路由,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
flutter之从零开始搭建(一)之 BottomNavigationBar
flutter之从零开始搭建(二)之 Navigator路由
flutter之从零开始搭建(二)之 网络请求
今天我们来讲讲利用Navigator来跳转页面的功能,承接上一篇flutter之从零开始搭建(一)之 BottomNavigationBar继续讲。
页面跳转是我们在入门学习的必备知识,在flutter中,路由跳转是由Navigator来操作的。
Navigator的跳转有两种,一种是显示跳转,需要我们在MaterialPageRoute中指定widget
Navigator.of(context).push(new MaterialPageRoute(builder: (context) {//指定跳转的页面return new Demo1();},));
另一种是隐身跳转,这种跳转需要先定义,后使用,跳转方式就像Arouter一样的路径方式,定义部分需要在MaterialApp下定义routes,routes就跟一个Map<path,Page>
集合一样,定义好了path对应的page,那么下次跳转,我们就可以针对path去跳转了
@overrideWidget build(BuildContext context) {return new MaterialApp(home: new Scaffold(body: new Center(child: new RaisedButton(onPressed: _pushPage,child: new Text("跳转"))),),//定义路由routes: <String,WidgetBuilder>{"/demo1":(BuildContext context)=>new Demo1(),},);
跳转使用
Navigator.of(context).pushNamed("/demo1");
知道路由如何跳转了,那么,我们开始实战吧
实战
我们看到,路由的跳转都带着一个context参数,这其中有无数的坑需要自己去理解,接下来我会展示出来。
还是承接上一篇博文flutter之从零开始搭建(一)之 BottomNavigationBar,我们先看下MyPage页面,先给出如下代码
import 'package:flutter/material.dart';
import 'package:codelang/widget/Demo1.dart';class MyPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return new MaterialApp(theme: new ThemeData(primarySwatch: Colors.blue,),debugShowCheckedModeBanner: false,home: new PageWidget(),routes: <String,WidgetBuilder>{"/demo1":(BuildContext context)=>new Demo1(),},);}
}class PageWidget extends StatefulWidget {@overrideState<StatefulWidget> createState() {// TODO: implement createStatereturn new PageState();}
}class PageState extends State<PageWidget> {@overrideWidget build(BuildContext context) {return new Scaffold(body: new Center(child: new RaisedButton(onPressed: _pushPage,child: new Text("跳转"),),),);}_pushPage(){// Navigator.of(context).pushNamed("/demo1");Navigator.of(context).push(new MaterialPageRoute(builder: (context) {return new Demo1();},));}
}
大家整体看一下代码,其实没什么错误的地方,看起来一切都很正常,然后我们来看下效果图
what fuck!!! 跳转的页面怎么没有覆盖全屏,所以,这种方式肯定是不可取的。
我们先停下来想想,我们当前页面PageState
是在PageWidget
布局上面,PageWidget还有一个上层布局叫MyPage
,我们是不是可以理解为,Navigator.of(context)
的这个context
指向的是上层MyPage
布局的context
,导致了页面路由跳转是在MyPage
页面进行。
那么有什么解决办法呢?既然是context原因,那么,我们必须得拿到MyPage
的上一层context
,我们再想想,MyPage
相当于一个fragment
,是由MainPage
页面组成的,我们只需要拿将MainPage
页面的context传递给MyPage
不就行了吗?接下来开干试试。
打开
MainPage
给MyPage的构造方法传递MainPage
的context
_bodys = [new HomePage(),new ShopPage(),new MsgPage(),new MyPage(context)];
打开
MyPage
MyPage拿到MainPage
的parentContext,然后将parentContext传递给PageWidget
,PageState
可以通过widget.X
的形式,可以拿到PageWidget
的变量
import 'package:flutter/material.dart';
import 'package:codelang/widget/Demo1.dart';class MyPage extends StatelessWidget {var parentContext;MyPage(this.parentContext);@overrideWidget build(BuildContext context) {return new MaterialApp(title: 'Flutter Demo',theme: new ThemeData(primarySwatch: Colors.blue,),debugShowCheckedModeBanner: false,home: new PageWidget(parentContext),routes: <String,WidgetBuilder>{"/demo1":(BuildContext context)=>new Demo1(),},);}
}class PageWidget extends StatefulWidget {var parentContext;PageWidget(this.parentContext);@overrideState<StatefulWidget> createState() {// TODO: implement createStatereturn new PageState();}
}class PageState extends State<PageWidget> {@overrideWidget build(BuildContext context) {return new Scaffold(body: new Center(child: new RaisedButton(onPressed: _pushPage,child: new Text("跳转"),),),);}_pushPage(){
// Navigator.of(widget.parentContext).pushNamed("/demo1");Navigator.of(widget.parentContext).push(new MaterialPageRoute(builder: (context) {return new Demo1();},));}
}
看下效果图
嗯,很完美的解决,大家有没有看到我_pushPage
方法中注释了的pushNamed
方式的跳转,大家猜猜,用这种方式会不会出错?5秒钟的思考哦.
- 倒计时5s
- 倒计时4s
- 倒计时3s
- 倒计时2s
- 倒计时1s
OK,来揭晓答案,肯定是不行的,我们知道,routes的定义是在MyPage
中的,而我们饿路由跳转拿到的parentContext
是MainPage
的,所以,会报找不到这个路由的错误,如何解决呢?我相信到这大家应该都清楚了,那就是在MainPage
中去定义这个routes,具体可以看如下
class MainPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return new MaterialApp(debugShowCheckedModeBanner: false,routes: <String, WidgetBuilder>{"/demo1": (BuildContext context) => new Demo1(),},home: new MainPageWidget());}
}
这样跳转就可以了,效果图我就不贴出来了,跟上面一样。
你以为就这样结束了?哈哈,早着呢,在写这篇博文的时候,我又发现了一个好玩的地方,为了区分,我在HomePage
页面去写这个例子,代码不多,大家看看
HomePage
import 'package:flutter/material.dart';
import 'package:codelang/widget/Demo1.dart';class HomePage extends StatefulWidget {@overrideState<StatefulWidget> createState() {// TODO: implement createStatereturn new HomeState();}
}class HomeState extends State<HomePage> {@overrideWidget build(BuildContext context) {// TODO: implement buildreturn new MaterialApp(debugShowCheckedModeBanner: false,home: new Scaffold(body: new Center(child: new RaisedButton(onPressed: _pushPage,child: new Text("跳转"))),),);}_pushPage() {
// Navigator.of(context).pushNamed("/demo1");Navigator.of(context).push(new MaterialPageRoute(builder: (context) {return new Demo1();},));}
}
在这个路由跳转中,我用了context来跳转,大家再猜猜,这种方式可以嘛?5秒钟的思考时间
- 倒计时5s
- 倒计时4s
- 倒计时3s
- 倒计时2s
- 倒计时1s
答案揭晓,是可以的哦,为什么这样又可以了呢?
HomePage
与MyPage
的区别在于定义这个widget时,MyPage
最外套的一层是StatelessWidget
,而HomePage
最外套的一层是StatefulWidget
,StatelessWidget
是一个无状态的widget,难道是他阻隔了context的传递?具体的我也不清楚,只能去猜。
大家再猜猜还是那段注释了的pushNamed
的代码,可不可以跳转呢?哈哈,当然是可以的,因为我们在前面的时候,就已经在mainPage
中定义了routes
好了,路由这篇说完了,唯一坑就是context的问题,看了这一篇,相信很多人都理解了Navigator如何跳转,下一篇再见吧
gayhub链接
这篇关于flutter之从零开始搭建(二)之 Navigator路由的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!