avatar

目录
从Flutter到原生开发-路由管理

Flutter路由管理

路由(Route)在移动开发中通常指页面(Page),这跟web开发中单页应用的Route概念意义是相同的,所谓路由管理,
就是管理页面之间如何跳转,通常也可被称为导航管理。Flutter中的路由管理和原生开发类似,无论是Android还是iOS,
导航管理都会维护一个路由栈,路由入栈(push)操作对应打开一个新页面,路由出栈(pop)操作对应页面关闭操作,
而路由管理主要是指如何来管理路由栈。

MaterialPageRoute

dart
1
2
3
4
5
6
MaterialPageRoute({
WidgetBuilder builder,
RouteSettings settings,
bool maintainState = true,
bool fullscreenDialog = false,
})
  1. builder 是一个WidgetBuilder类型的回调函数,它的作用是构建路由页面的具体内容,返回值是一个widget。我们通常要实现此回调,返回新路由的实例。
  2. settings 包含路由的配置信息,如路由名称、是否初始路由(首页)。
  3. maintainState:默认情况下,当入栈一个新路由时,原来的路由仍然会被保存在内存中,如果想在路由没用的时候释放其所占用的所有资源,可以设置maintainState为false。
  4. fullscreenDialog表示新的路由页面是否是一个全屏的模态对话框,在iOS中,如果fullscreenDialog为true,新页面将会从屏幕底部滑入(而不是水平方向)。

示例

  1. 创建一个新路由,命名“NewRoute”

    dart
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class NewRoute extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: Text("New route"),
    ),
    body: Center(
    child: Text("This is new route"),
    ),
    );
    }
    }
  2. 再 HomeWidget 中添加一个按钮

    dart
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    void main()=>runApp(new MyApp());
    class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return new MaterialApp(
    title: "demo1",
    home: HomeWidget()
    );
    }
    }
    class HomeWidget extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
    return new Scaffold(
    appBar: new AppBar(
    title: new Text("title"),
    ),
    body: new Container(
    margin: EdgeInsets.all(20.0),
    child: Column(
    children: <Widget>[
    FlatButton(
    child: Text("open new route"),
    textColor: Colors.blue[400],
    onPressed: () {
    Navigator.push(
    context, MaterialPageRoute(
    builder: (context) {return NewRoute();},
    maintainState: false,
    fullscreenDialog: false
    ));
    },
    )
    ],
    ),
    ),
    );
    }
    }
Navigator是一个路由管理的组件,它提供了打开和退出路由页方法。Navigator通过一个栈来管理活动路由集合。
通常当前屏幕显示的页面就是栈顶的路由。Navigator提供了一系列方法来管理路由栈
  • push(BuildContext context, Route route)
    将给定的路由入栈(即打开新的页面),返回值是一个Future对象,用以接收新路由出栈(即关闭)时的返回数据。
  • pop(BuildContext context, [ result ])
    将栈顶路由出栈,result为页面关闭时返回给上一个页面的数据。

    Navigator 还有很多其它方法,如Navigator.replace、Navigator.popUntil等,详情请参考API文档或SDK源码注释,在此不再赘述。

路由传值

很多时候,在路由跳转时我们需要带一些参数,比如打开商品详情页时,
我们需要带一个商品id,这样商品详情页才知道展示哪个商品信息;
又比如我们在填写订单时需要选择收货地址,打开地址选择页并选择地址后,
可以将用户选择的地址返回到订单页等等。下面我们通过一个简单的示例来演示新旧路由如何传参
  • 新建一个子页面

    dart
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    import 'package:flutter/material.dart';
    class TipRoutr extends StatelessWidget{
    TipRoutr({
    Key key,
    @required this.text,
    }):super(key:key);
    final String text;
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: Text("tishi"),
    ),
    body: Padding(
    padding: EdgeInsets.all(18),
    child: Center(
    child: Column(
    children: <Widget>[
    Text("text"),
    RaisedButton(
    onPressed: ()=>Navigator.pop(context,'我是返回值'),
    child: Text("返回"),
    )
    ],
    ),
    ),
    ),
    );
    }
    }
  • 新建一个父页面

    dart
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    import 'package:flutter/material.dart';
    import 'package:flutter_app1/router_Demo/TipRoute.dart';
    void main()=>runApp(MyApp());
    class MyApp extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    title: '123',
    home: Scaffold(
    appBar: AppBar(
    title: Text("123"),
    ),
    body: RouterTestRoute(),
    ),
    theme: ThemeData(colorScheme: ColorScheme.light(background: Colors.redAccent)),
    );
    }
    }

    class RouterTestRoute extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
    return Center(
    child: RaisedButton(
    onPressed: () async{
    var result = await Navigator.push(context, MaterialPageRoute(
    builder: (context){
    return TipRoutr(
    text: "woshi tishi",
    );
    },
    ),
    );
    print("luyou $result");
    },
    child: Text("open Tip"),
    ),
    );
    }
    }
  1. 提示文案“我是提示xxxx”是通过TipRoute的text参数传递给新路由页的。我们可以通过等待Navigator.push(…)返回的Future来获取新路由的返回数据。
  2. 在TipRoute页中有两种方式可以返回到上一页;第一种方式时直接点击导航栏返回箭头,第二种方式是点击页面中的“返回”按钮。这两种返回方式的区别是前者不会返回数据给上一个路由,而后者会。下面是分别点击页面中的返回按钮和导航栏返回箭头后,RouterTestRoute页中print方法在控制台输出的内容:
I/flutter (27896): 路由返回值: 我是返回值
I/flutter (27896): 路由返回值: null

命名路由

谓“命名路由”(Named Route)即有名字的路由,我们可以先给路由起一个名字,
然后就可以通过路由名字直接打开新的路由了,这为路由管理带来了一种直观、简单的方式。
  1. 定义routes

    dart
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    import 'package:flutter/material.dart';
    import 'pages3-22/DefaultPage.dart';
    import 'pages3-22/HomePage.dart';
    import 'pages3-22/ListPage.dart';
    import 'pages3-22/MePage.dart';
    import 'pages3-22/SearchPage.dart';

    void main() => runApp(App());

    class App extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    home: MyApp(),
    routes: {
    "/HomePage": (context) => HomePage(),
    "/DefaultPage": (context) => DefaultPage(),
    "/ListPage": (context) => ListPage(),
    "/MePage": (context) => MePage(),
    "/Search": (context) => SearchPage(),
    },
    );
    }
    }
  2. 在页面写跳转按钮

    dart
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

    import 'package:flutter/material.dart';

    class HomePage extends StatelessWidget {
    const HomePage({Key key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    return Container(
    child: Column(
    children: <Widget>[
    RaisedButton(
    onPressed: () {
    // 命名路由的跳转方式
    Navigator.pushNamed(context, "/Search");
    },
    child: Text("跳转到search页面并且传递id"),
    ),
    ],
    ),
    );
    }
    }
  3. 跳转的页面

    dart
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    import "package:flutter/material.dart";

    class SearchPage extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: Text("查询页面"),
    ),
    body: Container(
    child: Text("SearchPage"),
    ),
    );
    }
    }

命名路由传参

待更!

路由替换

dart
1
Navigator.pushReplacementNamed(context,'/routerName');

返回到上一个页面

dart
1
Navigator.of(context).pop();

返回到根页面

dart
1
2
3
4
Navigator.of(context).pushAndRemoveUntil(
new MaterialPageRoute(builder:(context)=>RouterName()),
(route)=>route==null
);
打赏
  • 微信
    微信
  • 支付寶
    支付寶

评论