本文主要是介绍Flutter学习(四):Navigator,Route,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Flutter应用中的页面跳转实现由Navigator,Route来实现.
Navigator
Navigator是一个路由管理的widget,它通过一个栈来管理一个路由widget集合。通常当前屏幕显示的页面就是栈顶的路由。Navigator提供了一系列方法来管理路由栈,在此我们只介绍其最常用的两个方法:
Future push(BuildContext context, Route route)
将给定的路由入栈(即打开新的页面),返回值是一个Future对象,用以接收新路由出栈(即关闭)时的返回数据。
bool pop(BuildContext context, [ result ])
将栈顶路由出栈,result为页面关闭时返回给上一个页面的数据。
Navigator 还有很多其它方法,如Navigator.replace、Navigator.popUntil等,详情请参考API文档或SDK源码注释.
实例方法
Navigator类中第一个参数为context的静态方法都对应一个Navigator的实例方法, 比如Navigator.push(BuildContext context, Route route)等价于Navigator.of(context).push(Route route) route) ,后面介绍的命名路由相关方法也是一样的。
我们在代码中测试一下使用
import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';void main() => runApp(new MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return new MaterialApp(title: 'Welcome to Flutter',home: new Scaffold(appBar: new AppBar(title: new Text('Welcome to Flutter'),),body: new Center(child: new RandomWordsWidget(),),bottomNavigationBar: new FlatButton(onPressed: () {Navigator.push(context, new MaterialPageRoute(builder: (context) {return new NewPage();}));},child: Text('跳转到新界面')),),);}
}class NewPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return new MaterialApp(title: 'New Page',home: new Scaffold(appBar: new AppBar(title: Text('New Page:Title'),),body: Text('New Page:Body'),),);}
}class RandomWordsWidget extends StatefulWidget {@overridecreateState() => new RandomWordsStatus();
}class RandomWordsStatus extends State<RandomWordsWidget> {@overrideWidget build(BuildContext context) {final wordPair = new WordPair.random();return new Text(wordPair.asPascalCase);}
}
我们在界面底部添加了一个导航栏,点击后将会跳转到一个新的界面.运行后,点击,发现没有效果,出现了一个异常:
I/flutter (28564): The following assertion was thrown while handling a gesture:
I/flutter (28564): Navigator operation requested with a context that does not include a Navigator.
I/flutter (28564): The context used to push or pop routes from the Navigator must be that of a widget that is a
I/flutter (28564): descendant of a Navigator widget.
I/flutter (28564): When the exception was thrown, this was the stack:
I/flutter (28564): #0 Navigator.of.<anonymous closure> (package:flutter/src/widgets/navigator.dart:1379:9)
I/flutter (28564): #1 Navigator.of (package:flutter/src/widgets/navigator.dart:1386:6)
I/flutter (28564): #2 Navigator.push (package:flutter/src/widgets/navigator.dart:1011:22)
I/flutter (28564): #3 MyApp.build.<anonymous closure> (package:flutter_demo/main.dart:20:25)
I/flutter (28564): #4 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:513:14)
I/flutter (28564): #5 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:568:30)
I/flutter (28564): #6 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:120:24)
I/flutter (28564): #7 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:242:9)
I/flutter (28564): #8 TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:175:7)
I/flutter (28564): #9 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:369:9)
I/flutter (28564): #10 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:73:12)
I/flutter (28564): #11 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:11)
异常显示,我们使用了一个不包含Navigator的Context来请求Navigator操作,而Navigator进行push或者pop操作时使用的Context必须是Navigator Widget的子类.
从代码中查看,我们使用的Context来自于build方法中,是从StatelessWidget中传递过来的.
具体的分析过程参考博文:
Flutter | 深入理解BuildContext
看过上文后,我们要解决这个问题,必须使用MaterialApp中的context.
我们将首页的代码提取一下,将Scaffold 提取出来,然后使用MaterialApp中的context.
具体代码如下:
import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';void main() => runApp(new MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return new MaterialApp(title: 'Welcome to Flutter',home: FirstPage(),);}
}
class FirstPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return new Scaffold(appBar: new AppBar(title: new Text('Welcome to Flutter'),),body: new Center(child: new RandomWordsWidget(),),bottomNavigationBar: new FlatButton(onPressed: () {Navigator.push(context, new MaterialPageRoute(builder: (context) {return new NewPage();}));},child: Text('跳转到新界面')),);}
}class NewPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return new MaterialApp(title: 'New Page',home: new Scaffold(appBar: new AppBar(title: Text('New Page:Title'),),body: Text('New Page:Body'),),);}
}class RandomWordsWidget extends StatefulWidget {@overridecreateState() => new RandomWordsStatus();
}class RandomWordsStatus extends State<RandomWordsWidget> {@overrideWidget build(BuildContext context) {final wordPair = new WordPair.random();return new Text(wordPair.asPascalCase);}
}
运行测试后完美
这篇关于Flutter学习(四):Navigator,Route的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!