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,),
          ],
        ),
      ),
    );
  }

}

 

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