欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

flutter: 具名路由用法

程序员文章站 2022-05-30 17:42:11
...

我们知道, 在flutter中, 我们可以通过Navigator.push()Navigator.pop()非常方便的控制路由,
但有时候我们希望路由统一管理路由, 这就需要具名路由了

在flutter中, 入口的MaterialApp组件中就有onGenerateRoute(总体路由)initialRoute(初始路由路径)两个参数.来统一管理路由. 我们可以写一个路由文件专门处理路由.同时,应该处理好路由传参\返回参\路由多级跳转的问题.

flutter: 具名路由用法
总路由入口位置
flutter: 具名路由用法
单独拆分一个文件处理路由

接下来,我们通过分析一个例子来学习路由中的具体问题,先看例子 , 提前剧透一下: 我们访问这种具名路由一般用Navigator.pushNamed()

flutter: 具名路由用法

接下来我们来分析这些路由

一. 无传参路由

无传参路由非常简单, 我们只需要把文件引入好, 在route中写好就可以了, 在调用时使用Navigator.pushNamed()调用

flutter: 具名路由用法
无参数路由
flutter: 具名路由用法

二. 有传参路由(静态)

有传参的路由, 我们需要:

  • 在路由管理文件中, 将参数传递到路由路径对应的跳转路由函数中
flutter: 具名路由用法
  • 目标静态页面/组件要留好形参, 做好参数接收工作
flutter: 具名路由用法
  • 准备好后,就开始调用此路由了, 调用时, 我们可以传递参数了
flutter: 具名路由用法

三. 有传参路由(动态)

动态和静态没有区别, 唯一的区别在于声明形参,做好接参工作的那一个环节

flutter: 具名路由用法

四. 有传参给动态且有返回

这种情况是比较综合一点的例子
和有传参路由(动态) 的区别是, 带了一个异步返回值

flutter: 具名路由用法

调用时:

flutter: 具名路由用法

五. 直接返回根目录

最后一个案例, 我们可以从第二步页面直接返回homepage 这是怎么做到的呢?
很简单, 第一步页面跳转到第二步页面时, 使用了Navigator.of(context).pushReplacementNamed('/register2'); 这样第二步页面替换了第一步页面, 所以对于第二步页面来说, 它的前一页还是 homepage

flutter: 具名路由用法

六. 全部代码

只是为了学习, 所以写的时候没规划目录, 也没有完全拆分.

flutter: 具名路由用法

main.dart

import 'package:flutter/material.dart';
import './routes/Routes.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData.light(),
      initialRoute: '/', //MaterialApp没有入口组件, 而有初始路由,会由此跳转到入口组件
      onGenerateRoute:
          onGenerateRoute, //总路由函数是来自 ./routes/Routes.dart下的onGenerateRoute函数
    );
  }
}

Routes

import 'package:flutter/material.dart';
import '../HomePage.dart';
import '../FormPage.dart';
import '../CatePage.dart';
import '../ProfilePage.dart';
import '../SettingPage.dart';
import '../register/Register1.dart';
import '../register/Register2.dart';

final routes = {
  '/': (context, {arguments}) => HomePage(arguments: arguments),
  '/form': (context) => FormPage(), //无传参路由
  '/cate': (context, {arguments}) => CatePage(arguments: arguments),//有传参(传给静态组件)
  '/profile': (context, {arguments}) => ProfilePage(arguments: arguments),//有传参(传给动态组件)
  '/set': (context, {arguments}) => SettingPage(arguments: arguments),//有传参给动态且接收返回值
  '/register1': (context) => Register1(),
  '/register2': (context) => Register2(),
};

//固定写法,为了处理路由的参数.
// ignore: missing_return, top_level_function_literal_block
var onGenerateRoute = (RouteSettings settings) {
  final String name = settings.name;
  final Function pageContentBuilder = routes[name];
  if (pageContentBuilder != null) {
    if (settings.arguments != null) {
      final Route route = MaterialPageRoute(
          builder: (context) =>
              pageContentBuilder(context, arguments: settings.arguments));
      return route;
    } else {
      final Route route =
          MaterialPageRoute(builder: (context) => pageContentBuilder(context));
      return route;
    }
  }
};

homepage

import 'package:flutter/material.dart';

//ignore:  must_be_immutable
class HomePage extends StatefulWidget {
  final Map arguments;
  int mycount = 1;
  HomePage({Key key, this.arguments}) : super(key: key);
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            RaisedButton(
              child: Text('无传参路由'),
              onPressed: () {
                Navigator.pushNamed(context, '/form');
              },
            ),
            RaisedButton(
              child: Text('传参的路由(静态)'),
              onPressed: () {
                Navigator.pushNamed(context, '/cate',
                    arguments: {"someArg": "这是一个小小的参数"});
              },
            ),
            RaisedButton(
              child: Text('传参的路由(动态)'),
              onPressed: () {
                Navigator.pushNamed(context, '/profile',
                    arguments: {"pid": 1231});
              },
            ),
            RaisedButton(
              child: Text('传参的路由(动态且返回):${widget.mycount}'),
              onPressed: () {
                Navigator.pushNamed(context, '/set',
                    arguments: {"id": widget.mycount}).then((v) {
                  setState(() {
                    widget.mycount = v;
                  });
                });
              },
            ),
            RaisedButton(
              child: Text('测试多层push一下返回根目录'),
              onPressed: () {
                Navigator.pushNamed(context, '/register1');
              },
            ),
          ],
        ),
      ),
    );
  }
}

FormPage

import 'package:flutter/material.dart';
class FormPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FormPage"),
      ),
      body: Text("data"),
    );
  }
}

CatePage

import 'package:flutter/material.dart';

class CatePage extends StatelessWidget {
  final Map arguments;
  CatePage({this.arguments});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("CatePage"),
      ),
      body: Text(arguments.toString()),
    );
  }
}

ProfilePage

import 'package:flutter/material.dart';

class ProfilePage extends StatefulWidget {
  final Map arguments; //如果要传参,就应该添加这两句, 在这里接收参数.
  ProfilePage({Key key, this.arguments}) : super(key: key); //在这里接收参数
  @override
  _ProfilePageState createState() => _ProfilePageState();
}

class _ProfilePageState extends State<ProfilePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ProfilePage"),
      ),
      body: Text(widget.arguments.toString()),
    );
  }
}

SettingPage

import 'package:flutter/material.dart';

class SettingPage extends StatefulWidget {
  final Map arguments;
  SettingPage({this.arguments});
  @override
  _SettingPageState createState() => _SettingPageState();
}

class _SettingPageState extends State<SettingPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("SettingPage"),
      ),
      body: Column(
        children: <Widget>[
          RaisedButton(
            child: Text(
                "传过来的参数:${widget.arguments != null ? widget.arguments['id'] : '0'}"),
            onPressed: () {
              setState(() {
                widget.arguments['id']++;
              });
            },
          ),
          RaisedButton(
              child: Text("带参数返回"),
              onPressed: () {
                print(widget.arguments['id']);
                Navigator.of(context).pop(widget.arguments['id']);
              })
        ],
      ),
    );
  }
}

Register1

import 'package:flutter/material.dart';

class Register1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('注册·第一步')),
      body: RaisedButton(
          child: Text("下一步"),
          onPressed: () {
            Navigator.of(context).pushReplacementNamed('/register2');
            //这样跳转register2页面会替换register1页面,所以register2页面返回时能直接回homepage
          }),
    );
  }
}

Register2

import 'package:flutter/material.dart';

class Register2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('注册·第二步'),
      ),
      body: RaisedButton(
          child: Text("完成注册,返回"),
          onPressed: () {
            Navigator.of(context).pop();
          }),
    );
  }
}