Flutter 页面跳转及参数传递

一、Flutter 页面跳转及参数传递

在Android中,可以通过Intents来在Activity之间切换或调用外部组件,但Flutter不具有Intents的概念,那么我们如何在Flutter中来实现屏幕切换呢?要在Flutter中切换屏幕,您可以访问路由以绘制新的Widget。 管理多个屏幕有两个核心概念和类:Route (路由)和 Navigator(导航器)。Route是应用程序的“屏幕”或“页面”的抽象(可以认为是Activity), Navigator是管理Route的Widget。Navigator可以通过push和pop route以实现页面切换。

Flutter和Android相似,Android中需要在AndroidManifest.xml中声明您的Activitie组件,在Flutter中,您可以将具有指定Route的Map传递到顶层MaterialApp,

首先我们看一下通过路由实现的页面切换效果图:

                                

其中点击跳转到RouteA中是通过pushName跳转的,没有携带数据。点击跳转到RouteB中是通过push跳转的,并且携带了一个对象,然后在RouteB中接收显示,在RouteB中返回的时候也将处理结果返回,在StudyRoute中接收处理RouteB返回的处理结果。下面我们看一下这两种route具体实现过程:

1、MaterialApp中的routes声明如下:

return new MaterialApp(
      theme: ThemeData(primarySwatch: Colors.blue),
      routes: <String, WidgetBuilder>{
        '/RouteA': (BuildContext context) {
          return new RouteA();
        },
        '/RouteB': (BuildContext context) {
          return new RouteB(product: new Product("测试", "我是描述"),);
        },
      },
      ...
    );

2、通过Navigator指定跳转

  • 通过pushNamed跳转页面,这种方式跳转的时候一般没法传递数据,但可以接收返回值。类似与Android的startActivityForResult

Navigator.pushNamed(context, '/RouteA').then((Object result) async {
   print('======$result');
});

或者

Navigator.of(context).pushNamed('/RouteA').then((Object result){
   print('======$result');
});

注意:通过pushNamed跳转的路由必须在MaterialApp的routes中声明路由跳转路径。

  • 通过push的方式跳转页面,同时传递数据到下一个页面,并接收处理后的结果
Navigator.push<String>(context,
        new MaterialPageRoute(builder: (BuildContext context) {
          return new RouteB(product: _product,);
        }),).then((String result){
          print("===================$result");
    });

3、实现案例目录

           

StudyRoute代码如下:
class StudyRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new MaterialApp(
      theme: ThemeData(primarySwatch: Colors.blue),
      routes: <String, WidgetBuilder>{
        '/RouteA': (BuildContext context) {
          return new RouteA();
        },
        '/RouteB': (BuildContext context) {
          return new RouteB(product: new Product("测试", "我是描述"),);
        },
      },
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Flutter Route使用'),
        ),
        body: new Study(),
      ),
    );
  }
}

class Study extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    Product product = new Product("Intent在Flutter中等价于什么?", "在Android中,Intents主要有两种使用场景:在Activity之间切换,以及调用外部组件。 Flutter不具有Intents的概念,但如果需要的话,Flutter可以通过Native整合来触发Intents。要在Flutter中切换屏幕,您可以访问路由以绘制新的Widget。 管理多个屏幕有两个核心概念和类:Route 和 Navigator。Route是应用程序的“屏幕”或“页面”的抽象(可以认为是Activity), Navigator是管理Route的Widget。Navigator可以通过push和pop route以实现页面切换。和Android相似,您可以在AndroidManifest.xml中声明您的Activities,在Flutter中,您可以将具有指定Route的Map传递到顶层MaterialApp实例");
    return _StudyState(product);
  }
}

class _StudyState extends State<Study> {
  final Product _product;

  _StudyState(this._product);
  void _onTapA() {
    Navigator.pushNamed(context, '/RouteA');
    Navigator.of(context).pushNamed('/RouteA');
  }

  void _onTapB() {
    Navigator.push<String>(context,
        new MaterialPageRoute(builder: (BuildContext context) {
          return new RouteB(product: _product,);
        }),).then((String result){
          print("===================$result");
        //Fluttertoast.showToast(msg: result);
    });
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Center(
      child: new Container(
        width: 300,
        height: 300,
        //color: Colors.blueAccent,
        child: new Column(
          children: <Widget>[
            new Expanded(
              flex: 1,
              child: new Container(
                width: 300,
                //color: Colors.red,
                decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.red),
                child: new InkWell(
                  onTap: _onTapA,
                  child: new Center(
                    child: new Text('跳转到Route A'),
                  )
                ),
              ),
            ),
            new Expanded(
              flex: 1,
              child: new Container(
                width: 300,
                decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.green),
                child: new InkWell(
                  onTap: _onTapB,
                  child: new Center(
                    child: new Text('跳转到Route B',textAlign: TextAlign.center),
                  )
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
通过pushName跳转到RouteA,并且通过pop返回到StudyRoute页面。
class RouteA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      //automaticallyImplyLeading: false关闭返回的部件
      appBar: new AppBar(
        title: new Text('我是Route A'),
        leading: Builder(builder: (BuildContext context) {
          return new IconButton(
              icon: Icon(Icons.arrow_back),
              onPressed: () {
                Navigator.pop(context, "携带的参数");
              });
        }),
      ),
      body: new Container(
        child: new Center(
          child: new Text('Route A 页面显示'),
        )
      ),
    );
  }
}

在RouteB中接收StudyRoute传递过来的参数并显示,同时用户点击返回的时候将返回结果回传给StudyRoute

class RouteB extends StatelessWidget{
  final Product product;
  const RouteB({Key key, @required this.product}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Flutter RouteB'),
        leading: Builder(builder: (BuildContext context){
          return new IconButton(icon: Icon(Icons.arrow_back_ios), onPressed:(){
              Navigator.pop(context,"我是返回的数据");
          });
        }),
      ),
      body: new Center(
        child: new Column(
          children: <Widget>[
            new Text(product.title,style: TextStyle(color: Color(0xFF333333),fontSize: 18,fontWeight: FontWeight.bold),),
            new Text(product.description,softWrap: true,),
          ],
        ),
      ),
    );
  }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章