Flutter:路由管理

xiaohai 2021-08-10 20:12:17 247人围观 标签: Flutter 
简介Flutter 提供了基本路由和命名路由两种方式,来管理页面间的跳转。其中,基本路由需要自己手动创建页面实例,通过 Navigator.push 完成页面跳转;而命名路由需要提前注册页面标识符和页面创建方法,通过 Navigator.pushNamed 传入标识符实现页面跳转。

Flutter 提供了基本路由和命名路由两种方式,来管理页面间的跳转。其中,基本路由需要自己手动创建页面实例,通过 Navigator.push 完成页面跳转;而命名路由需要提前注册页面标识符和页面创建方法,通过 Navigator.pushNamed 传入标识符实现页面跳转。

一、基本路由
1.1、基本路由跳转

基本路由跳转主要代码是:

Navigator.push(context, MaterialPageRoute(builder: (context) {
    return OnePage();//页面类
}));

全部代码如下:

import 'package:flutter/material.dart';

void main() {
  runApp(new App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        // appBar: AppBar(
        //   title: new Text('MaterialApp示例'),
        // ),
        body: AppHomePage(),
      ),
      color: Colors.yellow,
      debugShowMaterialGrid: false, //显示网格
      debugShowCheckedModeBanner: false, //去掉右上角的debug
      title: 'Material Design', //标题
      theme: ThemeData(
        primaryColor: Colors.yellow[500], //设置应用的主要颜色为黄色
      ),
    );
  }
}

class AppHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text("首页"),
        TextButton(
          onPressed: () {
            Navigator.push(context, MaterialPageRoute(builder: (context) {
              return OnePage();
            }));
          },
          child: Text("基本路由跳转"),
        )
      ],
    ));
  }
}

//新页面
class OnePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('基本路由跳转页面'),
        elevation: 0.0,
      ),
      body: Center(
        child: Text("基本路由跳转页面"),
      ),
    );
  }
}
1.2、基本路由A->B传递参数

需要在B页面的类新增构造方法,因为我这里使用的StatelessWidget组件

final String title;
OnePage({Key? key, required this.title}) : super(key: key);

然后在A页面的路由跳转中传递值即可:

Navigator.push(context, MaterialPageRoute(builder: (context) {
    return OnePage(
        title: '我是Flutter',
    );
}));

完整代码如下:

import 'package:flutter/material.dart';

void main() {
  runApp(new App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        // appBar: AppBar(
        //   title: new Text('MaterialApp示例'),
        // ),
        body: AppHomePage(),
      ),
      color: Colors.yellow,
      debugShowMaterialGrid: false, //显示网格
      debugShowCheckedModeBanner: false, //去掉右上角的debug
      title: 'Material Design', //标题
      theme: ThemeData(
        primaryColor: Colors.yellow[500], //设置应用的主要颜色为黄色
      ),
    );
  }
}

class AppHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text("首页"),
        TextButton(
          onPressed: () {
            Navigator.push(context, MaterialPageRoute(builder: (context) {
              return OnePage(
                title: '我是Flutter',
              );
            }));
          },
          child: Text("基本路由跳转"),
        )
      ],
    ));
  }
}

class OnePage extends StatelessWidget {
  // Declare a field that holds the Todo
  final String title;

  OnePage({Key? key, required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('基本路由跳转页面'),
        elevation: 0.0,
      ),
      body: Center(
        child: Text('基本路由跳转页面-传值内容:$title'),
      ),
    );
  }
}
1.3、基本路由B页面返回到A页面传值

路由弹出栈添加参数

Navigator.pop(context, '我是返回值');

路由入栈处理,需要异步接收,关键字async和await

onPressed: () async {
    var result = await Navigator.push(context,
        MaterialPageRoute(builder: (context) {
            return OnePage(
                title: '我是Flutter',
        );
    }));
    print(result);
},

这里直接打印出来的结果。

完整代码如下:

import 'package:flutter/material.dart';

void main() {
  runApp(new App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        // appBar: AppBar(
        //   title: new Text('MaterialApp示例'),
        // ),
        body: AppHomePage(),
      ),
      color: Colors.yellow,
      debugShowMaterialGrid: false, //显示网格
      debugShowCheckedModeBanner: false, //去掉右上角的debug
      title: 'Material Design', //标题
      theme: ThemeData(
        primaryColor: Colors.yellow[500], //设置应用的主要颜色为黄色
      ),
    );
  }
}

class AppHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text("首页"),
        TextButton(
          onPressed: () async {
            var result = await Navigator.push(context,
                MaterialPageRoute(builder: (context) {
              return OnePage(
                title: '我是Flutter',
              );
            }));
            print(result);
          },
          child: Text("基本路由跳转"),
        )
      ],
    ));
  }
}

class OnePage extends StatelessWidget {
  // Declare a field that holds the Todo
  final String title;

  OnePage({Key? key, required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('基本路由跳转页面'),
        elevation: 0.0,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('基本路由跳转页面-传值内容:$title'),
            TextButton(
              onPressed: () {
                Navigator.pop(context, '我是返回值');
              },
              child: Text("返回"),
            )
          ],
        ),
      ),
    );
  }
}
二、命名路由

所谓“命名路由”(Named Route)即有名字的路由,我们可以先给路由起一个名字,然后就可以通过路由名字直接打开新的路由了,这为路由管理带来了一种直观、简单的方式。还记得前面的MaterialApp中的routes参数吗?它就是配置路由表的。

routes对象是一个Map。当使用Navigator.pushNamed来处理理由的时候,会在routes中查找路由名字,然后使用对应WidgetBuilder来构造一个带有页面切换动画MaterialPageRoute。使用routes是给MaterialApp组件初始化一个路由表,并且可以使用initialRoute设置一个初始化路由。

2.1、路由使用步骤
  • 设置路由表
    routes: {
    'one_page': (BuildContext context) => OnePage(), //第一个页面
    'two_page': (BuildContext context) => TwoPage(), //第二个页面
    },
    
  • 设置初始化路由
    initialRoute: 'one_page',
    
  • 路由跳转
    Navigator.pushNamed(context, 'two_page');
    

完整代码如下:

import 'package:flutter/material.dart';

void main() {
  runApp(new App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        // appBar: AppBar(
        //   title: new Text('MaterialApp示例'),
        // ),
        body: AppHomePage(),
      ),
      //注册路由
      routes: {
        "one_page": (context) => OnePage(
              title: "我是来自命名路由",
            ),
        "home": (context) => AppHomePage(),
      },
      initialRoute: 'home',
      color: Colors.yellow,
      debugShowMaterialGrid: false, //显示网格
      debugShowCheckedModeBanner: false, //去掉右上角的debug
      title: 'Material Design', //标题
      theme: ThemeData(
        primaryColor: Colors.yellow[500], //设置应用的主要颜色为黄色
      ),
    );
  }
}

class AppHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text("首页"),
        TextButton(
          onPressed: () async {
            var result = await Navigator.push(context,
                MaterialPageRoute(builder: (context) {
              return OnePage(
                title: '我是Flutter',
              );
            }));
            print(result);
          },
          child: Text("基本路由跳转"),
        ),
        TextButton(
            onPressed: () {
              Navigator.pushNamed(context, "one_page");
            },
            child: Text("命名路由跳转"))
      ],
    ));
  }
}

class OnePage extends StatelessWidget {
  // Declare a field that holds the Todo
  final String title;

  OnePage({Key? key, required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('基本路由跳转页面'),
        elevation: 0.0,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('基本路由跳转页面-传值内容:$title'),
            TextButton(
              onPressed: () {
                Navigator.pop(context, '我是返回值');
              },
              child: Text("返回"),
            )
          ],
        ),
      ),
    );
  }
}
2.2、路由传递参数

在路由页通过RouteSetting对象获取路由参数

class OnePage extends StatelessWidget {
  //省略代码
  @override
  Widget build(BuildContext context) {
    var args = ModalRoute.of(context)!.settings.arguments;
    print(args);
    //省略代码
  }
}

在打开路由时传递参数

Navigator.of(context)
                  .pushNamed("one_page", arguments: "命名路由传的的参数");