【Flutter 实战】路由堆栈详解

移动开发 作者: 2024-08-25 09:25:01
老孟导读:Flutter中路由是非常重要的部分,任何一个应用程序都离不开路由管理,此文讲解路由相关方法的使用和路由堆栈的变化。 Flutter 路由管理中有两个非常重要的概念: Route:路由是应用
  • Route:路由是应用程序页面的抽象,对应 Android 中 Activity 和 iOS 中的 ViewController,由 Navigator 管理。
  • Navigator:Navigator 是一个组件,管理和维护一个基于堆栈的历史记录,通过 push 和 pop 进行页面的跳转。

push 和 pop

class APage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,child: RaisedButton(
        child: Text('A 页面'),onPressed: () {
          Navigator.of(context).push(MaterialPageRoute(builder: (context) {
            return BPage();
          }));
        },),);
  }
}
class BPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        alignment: Alignment.center,child: RaisedButton(
          child: Text('B 页面'),onPressed: () {

          },);
  }
}
RaisedButton(
  child: Text('B 页面'),onPressed: () {
    Navigator.of(context).pop();
  },)
RaisedButton(
  child: Text('B 页面'),onPressed: () {
    Navigator.of(context).push(MaterialPageRoute(builder: (context) {
      return APage();
    }));
  },)
  1. 试想如下场景,进入购物App,展示购物列表,点击其中一个进入商品详细页面,使用 push 再次进入购物列表,然后在进入商品详细页面...,如此反复,路由堆栈中将会存放大量的购物列表和商品详细页面的路由,点击返回按钮,会将反复显示购物列表和商品详细页面。
  2. 页面切换时路由动画 push 和 pop 是不同。

maybePop 和 canPop

RaisedButton(
  child: Text('A 页面'),)
RaisedButton(
  child: Text('A 页面'),onPressed: () {
    Navigator.of(context).maybePop();
  },)
RaisedButton(
  child: Text('B 页面'),onPressed: () {
    if(Navigator.of(context).canPop()){
      Navigator.of(context).pop();
    }
  },)

pushNamed

MaterialApp(
      title: 'Flutter Demo',routes: <String,WidgetBuilder>{
        '/A': (context) => APage(),'/B': (context) => BPage(),},home: Scaffold(
        body: APage(),)
RaisedButton(
  child: Text('A 页面'),onPressed: () {
    Navigator.of(context).pushNamed('/B');
  },)

pushReplacementNamed 和 popAndPushNamed

RaisedButton(
  child: Text('A 页面'),)
RaisedButton(
  child: Text('B 页面'),onPressed: () {
      Navigator.of(context).pushReplacementNamed('/C');
  },)
RaisedButton(
  child: Text('C 页面'),)
RaisedButton(
  child: Text('B 页面'),onPressed: () {
      Navigator.of(context).popAndPushNamed('/C');
  },)
  • 欢迎页面:应用程序打开后首先进入欢迎界面,然后进入首页,进入首页后不应该再进入欢迎界面。
  • 登录页面:登录成功后进入相关页面,此时按返回按钮,不应再进入登录页面。

pushNamedAndRemoveUntil

RaisedButton(
  child: Text('C 页面'),onPressed: () {
    Navigator.of(context).pushNamedAndRemoveUntil('/D',ModalRoute.withName('/B'));
  },
RaisedButton(
  child: Text('D 页面'),)
Navigator.of(context).pushNamedAndRemoveUntil('/D',ModalRoute.withName('/B'));
Navigator.of(context).pushNamedAndRemoveUntil('/D',(Route route)=>false);

popUntil

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

传递数据

class ProductDetail extends StatelessWidget {
  final ProductInfo productInfo;

  const ProductDetail({Key key,this.productInfo}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
Navigator.of(context).push(MaterialPageRoute(builder: (context){
  return ProductDetail(productInfo: productInfo,);
}));
RaisedButton(
  child: Text('A 页面'),onPressed: () {
    Navigator.of(context).pushNamed('/B',arguments: '来自A');
  },)
RaisedButton(
  child: Text('${ModalRoute.of(context).settings.arguments}'),onPressed: () {
    Navigator.of(context).pushNamed('/C');
  },)

返回数据

RaisedButton(
  child: Text('${ModalRoute.of(context).settings.arguments}'),onPressed: () {
    Navigator.of(context).pop('从B返回');
  },)
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;
            });
          },);
  }
}
原创声明
本站部分文章基于互联网的整理,我们会把真正“有用/优质”的文章整理提供给各位开发者。本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
本文链接:http://www.jiecseo.com/news/show_68319.html