当前位置:   article > 正文

Flutter之路由跳转(上)_flutter路由跳转

flutter路由跳转
一、基础知识

核心概念

RouteNavigator
1.route:应用程序页面的抽象
2.Navigator,是一个组件管理和维护基于堆栈的历史记录,使用pop和push跳转页面页面间的跳转。


Navigator如何管理携带值的路由跳转
Navigator是一个栈结构,通过push 和pop来操作。push加入一个Route,并将返回一个Future对象。Future push(BuildContext context, Route route) pop则将栈顶元素出栈。 bool pop(BuildContext context, [ result ])result为页面关闭时返回给上一个页面的数据。 命名的路由(Named Route)Navigator类中第一个参数为context的静态方法都对应一个Navigator的实例方法, 比如Navigator.push(BuildContext context, Route route)等价Navigator.of(context).push(Route route)很多情况下在路由跳转时我们需要带一些参数,比如打开商品详情页时,我们需要带一个商品id,这样商品详情页才知道展示哪个商品信息;又比如我们在填写订单时需要选择收货地址,打开地址选择页后,可以将用户选择的地址返回到订单页等等。非命名路由传值:通过Navigator.push(context,route)来传递。值传回:Navigator.pop(context,result),result就是要返回的值。

Navigator 继承自 StatefulWidget,它也是小组件,它有很多相关静态函数,可以帮我们达到页面跳转和数据交互的功能:
push 将设置的router信息推送到Navigator上,实现页面跳转。
of 主要是获取 Navigator最近实例的好状态。
pop 导航到新页面,或者返回到上个页面。
canPop 判断是否可以导航到新页面
maybePop 可能会导航到新页面
popAndPushNamed 指定一个路由路径,并导航到新页面。
popUntil 反复执行pop 直到该函数的参数predicate返回true为止。
pushAndRemoveUntil 将给定路由推送到Navigator,删除先前的路由,直到该函数的参数predicate返回true为止。
pushNamed 将命名路由推送到Navigator。
pushNamedAndRemoveUntil 将命名路由推送到Navigator,删除先前的路由,直到该函数的参数predicate返回true为止。
pushReplacement 路由替换。
pushReplacementNamed 这个也是替换路由操作。推送一个命名路由到Navigator,新路由完成动画之后处理上一个路由。
removeRoute 从Navigator中删除路由,同时执行Route.dispose操作。
removeRouteBelow 从Navigator中删除路由,同时执行Route.dispose操作,要替换的路由是传入参数anchorRouter里面的路由。
replace 将Navigator中的路由替换成一个新路由。
replaceRouteBelow 将Navigator中的路由替换成一个新路由,要替换的路由是是传入参数anchorRouter里面的路由。

二、路由导航

Flutter 通过 Navigator 来进行页面之间的跳转,分为 push 系列和 pop 系列操作,带 push 方法为入栈操作,带pop 方法为出栈操作。Navigator 的 push 方法分两类,一类是带 Name 的,需要在 MaterialApp 下将 routers 属性进行注册,否则将会找不到该路由,还有一个是不带 Name 的,可以通过 Router 直接跳转。

Navigator.of(context).push(MaterailPageRoute(builder:(context){return BPage();}))
Navigator.of(context).pop();
Navigator.of(context).maybePop();
  • 1
  • 2
  • 3

pushNamed

pushNamed 是命名路由的方式,需要在 MaterialApp 中配置路由名称:

MaterialApp(
      title: 'Flutter Demo',
      routes: <String, WidgetBuilder>{
        '/A': (context) => APage(),
        '/B': (context) => BPage(),
      },
      home: Scaffold(
        body: APage(),
      ),
    )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  Navigator.of(context).pushNamed('/B');
  • 1

pushReplacementNamed 和 popAndPushNamed
有A、B、C 三个页面,A页面通过 pushNamed 跳转到 B:
在A页面执行跳转到B

Navigator.of(context).pushNamed('/B');
  • 1

在B页面执行替换并跳转跳转到C

Navigator.of(context).pushReplacementNamed('/C')
  • 1

在C页面执行

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

发现页面直接返回到A页面
从B页面执行Navigator.of(context).popAndPushNamed

发现popAndPushNamed 路由堆栈和 pushReplacementNamed 是一样,唯一的区别就是 popAndPushNamed 有 B 页面退出动画

pushNamedAndRemoveUntil
有A、B、C、D 四个页面,A 通过push进入 B 页面,B 通过push进入 C 页面,C 通过 pushNamedAndRemoveUntil 进入 D 页面同时删除路由堆栈中直到 /B 的路由,C 页面代码:

RaisedButton(
  child: Text('C 页面'),
  onPressed: () {
    Navigator.of(context).pushNamedAndRemoveUntil('/D', ModalRoute.withName('/B'));
  },
),
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

D 页面按钮执行 pop:

RaisedButton(
  child: Text('D 页面'),
  onPressed: () {
    Navigator.of(context).pop();
  },
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果想只保留最后的D路由

 Navigator.of(context).pushNamedAndRemoveUntil('/D', (Route route)=>false);
  • 1

popUntil

有如下场景,在入职新公司的时候,需要填写各种信息,这些信息分为不同部分,比如基本信息、工作信息、家庭信息等,这些不同模块在不同页面,填写信息时可以返回上一页,也可以取消,取消返回到首页,此场景可以使用 popUntil,一直 pop 到指定的页面。

RaisedButton(
  child: Text('D 页面'),
  onPressed: () {
    Navigator.of(context).popUntil(ModalRoute.withName('/A'));
  },
)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

传递数据
有两种方式传递数据:
第一种:通过构造函数方式:

Navigator.of(context).push(MaterialPageRoute(builder: (context){
  return ProductDetail(productInfo: productInfo,);
})); 
  • 1
  • 2
  • 3

通过命名路由设置参数的方式

RaisedButton(
  child: Text('A 页面'),
  onPressed: () {
    Navigator.of(context).pushNamed('/B',arguments: '来自A');
  },
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

B 页面通过 ModalRoute.of(context).settings.arguments 接收数据:

RaisedButton(
  child: Text('${ModalRoute.of(context).settings.arguments}'),
  onPressed: () {
    Navigator.of(context).pushNamed('/C');
  },
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

返回数据
B 页面返回代码

RaisedButton(
  child: Text('${ModalRoute.of(context).settings.arguments}'),
  onPressed: () {
    Navigator.of(context).pop('从B返回');
  },
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

A 页面接收返回的数据:

class APage extends StatefulWidget {
  @override
  _APageState createState() => _APageState();
}

class _APageState extends State<APage> {
  String _string = 'A 页面';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        alignment: Alignment.center,
        child: RaisedButton(
          child: Text(_string),
          onPressed: () async {
            var result =
                await Navigator.of(context).pushNamed('/B', arguments: '来自A');
            setState(() {
              _string = result;
            });
          },
        ),
      ),
    );
  }
}
  • 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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/418427
推荐阅读
相关标签
  

闽ICP备14008679号