“跳转页面”为啥加双引号,其实所谓的跳转页面可能和以前认识的不太一样。因为在Flutter
里,所有能看到的东西一般都是widget
,但是,没有说那个app是由一个页面构成的,所以,这个概念确实还是有的。这个功能的实现需要用到两个东西Route
和Navigator
。
Using the Navigator
Mobile apps typically reveal their contents via full-screen elements called "screens" or "pages". In Flutter these elements are called routes and they're managed by a Navigator widget. The navigator manages a stack of Route objects and provides methods for managing the stack, like Navigator.push and Navigator.pop.
班门弄斧的翻译一下子:手机应用们一般吧全屏的元素叫做“screens”或者“pages”。然而在Flutter里,我们叫做“routes”。它们用“Navigator”来管理。Navigator
管理了一个由Route
组成的堆栈,并提供了一些方法方便去管理这个堆栈,比如说:Navigator.push
和Navigator.pop
Displaying a full-screen route
Although you can create a navigator directly, it's most common to use the navigator created by a WidgetsApp or a MaterialApp widget. You can refer to that navigator with Navigator.of.
A MaterialApp is the simplest way to set things up. The MaterialApp's home becomes the route at the bottom of the Navigator's stack. It is what you see when the app is launched.
尽管你可以直接创建一个navigator
,但是最常用的还是通过WidgetsApp
和MaterialApp
这两个widget,你可以参考Navigator.of
。
MaterialApp
是最简单的一个方式。MaterialApp
的home
则会成为Navigator
栈的底端,就是当app刚启动的时候你看到的那个东西。eg:
void main() {
runApp(new MaterialApp(home: new MyAppHome()));
}
To push a new route on the stack you can create an instance of MaterialPageRoute with a builder function that creates whatever you want to appear on the screen. For example:
如果你想在栈里放一个新route
的话,你可以通过一个builder
方法来创建一个MaterialPageRoute
对象。eg:
Navigator.push(context, new MaterialPageRoute<void>(
builder: (BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('My Page')),
body: new Center(
child: new FlatButton(
child: new Text('POP'),
onPressed: () {
Navigator.pop(context);
},
),
),
);
},
));
新的route
通过Navigator
的pop
方法可以被出栈,返回app的首页。
Navigator.pop(context);
The route defines its widget with a builder function instead of a child widget because it will be built and rebuilt in different contexts depending on when it's pushed and popped.
这个route
之所以用builder
方法来定义而不是直接用一个widget
,是因为它在进出栈的时候需要根据不同的上下文来进行构建。
It usually isn't necessary to provide a widget that pops the Navigator in a route with a Scaffold because the Scaffold automatically adds a 'back' button to its AppBar. Pressing the back button causes Navigator.popto be called. On Android, pressing the system back button does the same thing.
通常情况下,如果用的是Scaffold
的话,是不需要我们手动去添加一个返回按钮的。它会自动的在左上角添加一个返回按钮,点击这个返回按钮就会调用Navigator.pop
方法,在安卓上,按压系统的返回按钮效果是一样的。
Using named navigator routes 使用命好名的
route
Mobile apps often manage a large number of routes and it's often easiest to refer to them by name. Route names, by convention, use a path-like structure (for example, '/a/b/c'). The app's home page route is named '/' by default.
app通常需要管理大量的route
,并且他们经常很容易的通过名字来找到它们。route
的名字,按照惯例,用类似路径的结构(比如:‘a/b/c’)。app的首页路径默认为'/'
The MaterialApp can be created with a
Map<String, WidgetBuilder>
which maps from a route's name to a builder function that will create it. The MaterialApp uses this map to create a value for its navigator's onGenerateRoute callback.
MaterialApp
创建的时候可以带着一个Map,而这个Map描述了route
的名字和对应的builder
方法。MaterialApp
就是根据这个Map在navigator
的onGenerateRoute
回调里创建对应的route
void main() {
runApp(new MaterialApp(
home: new MyAppHome(), // becomes the route named '/'
routes: <String, WidgetBuilder> {
'/a': (BuildContext context) => new MyPage(title: 'page A'),
'/b': (BuildContext context) => new MyPage(title: 'page B'),
'/c': (BuildContext context) => new MyPage(title: 'page C'),
},
));
}
个人认为,这种写法类似于Android里面清单文件的作用。
Navigator.pushNamed(context, '/b');