Flutter入門進階之旅(十三)Flutter 路由

Flutter路由介紹

跟Web頁或者原生APP同樣,咱們在使用Flutter 開發APP時也會涉及到多頁面之間的跳轉、參數傳遞、參數回傳等業務,Flutter路由能知足上述咱們提到的全部業務類型,此外咱們也能夠結合Flutter動畫給路由跳頁時添加個性化的跳頁動畫操做,我會在後續Flutter動畫章節中具體講解。經過本節專題,讀者不單單能夠本身動手作一些簡單的UI,還能利用Fluttter 路由結合以前的課程分享作一些簡單的多頁面Flutter App。java

本期課程目標
  • 瞭解並掌握Flutter路由的簡單使用
  • 掌握Flutter動態路由跟靜態路由的區別
  • 掌握Flutter路由在頁面間的參數傳遞以及回傳流程
  • 藉助路由結合以前的課程作一些簡單的多頁面Flutter APP

關於靜態路由跟動態路由

在Flutter中路由分爲靜態路由動態路由兩種:Flutter中所謂的靜態路由指的是須要提早把各個須要跳轉的頁面路徑註冊在routes: <String, WidgetBuilder> {}中,且靜態路由不支持向下一個頁面傳遞參數,可是能夠接收下一個頁面的返回值。 動態路由使用就相對來講比較靈活一點,動態路由一樣支持向下一個頁面傳遞參數,並且在使用時不須要咱們提早規劃好頁面路徑,只須要在具體跳頁邏輯中本身去構造MaterialPageRoute對象來完成頁面跳轉,或者用PageRouterBuilder來自定義路由跳轉時的動畫,關於路由跳轉動畫我會在Flutter動畫章節中具體講解,固然動態路由一樣也支持頁面參數回傳。app

路由場景分類

1.靜態路由跳頁

場景一:點擊A頁面中的按鈕跳轉到B頁,不涉及到數據傳遞以及回傳less

效果圖 ide

靜態路由跳頁
靜態路由使用時要求咱們在 MaterialApp中的routes中提早註冊路由

new MaterialApp(
      home: new FlutterDemo(),
      routes: <String, WidgetBuilder>{
        'router/new_page': (_) => new StaticNavigatorPage()
      }));
      
複製代碼

A頁面代碼測試

import 'package:flutter/material.dart';
import 'package:flutter_app/pages/simpleWidget/navigator/StaticNavigatorPage.dart';

void main() {
  runApp(new MaterialApp(
      home: new FlutterDemo(),
      routes: <String, WidgetBuilder>{
        'router/new_page': (_) => new StaticNavigatorPage()
      }));
}

class FlutterDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Flutter進階之旅"),
      ),
      body: new Center(
          child: new RaisedButton(
              child: new Text("靜態路由跳頁"),
              onPressed: () {
                Navigator.of(context)
                    .pushNamed('router/new_page'); //這裏必定要保證跳頁的路由路徑跟上面註冊的路徑一致
              })),
    );
  }
}
複製代碼

B頁面代碼動畫

import 'package:flutter/material.dart';

class StaticNavigatorPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("靜態路由頁"),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: () {
          Navigator.of(context).pop();
        },
        child: new Text("返回"),
      ),
      body: new Center(
        child: Text("靜態路由能夠傳入一個routes參數來定義路由。可是這裏定義的路由是靜態的,"
            "它不能夠向下一個頁面傳遞參數,利用push到一個新頁面,pushNamed方法是有一個Future的返回值的"
            ",因此靜態路由也是能夠接收下一個頁面的返回值的。可是不能向下一個頁面傳遞參數"),
      ),
    );
  }
}
複製代碼

上述藉助路由跳頁過程當中咱們注意到,大概分如下幾步: 1.註冊路由且保證路由的惟一性 2.跳頁時使用Navigator.of(context).pushNamed('路由地址'); 3.使用Navigator.of(context).pop();結束當前頁ui

2.靜態路由跳頁接收下一頁的返回值

場景二:點擊A頁面上的按鈕跳頁到B頁面,在B頁面銷燬後A頁面接收到B頁面回傳回來的值而且顯示在AlertDialogthis

效果圖 spa

靜態路由回傳數據
A頁面代碼: 使用Navigator push一個新頁面,pushNamed方法是有一個Future的返回值的,在then回調中監聽並接收新頁面回傳回來的數據,而且藉助 showDialog顯示在 Dialog

import 'package:flutter/material.dart';
import 'package:flutter_app/pages/simpleWidget/navigator/StaticNavigatorPageWithParams.dart';

void main() {
  runApp(
      new MaterialApp(home: new FlutterDemo(), routes: <String, WidgetBuilder>{
    'router/new_page_with_callback': (_) => new StaticNavigatorPageWithResult()
  }));
}

class FlutterDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Flutter進階之旅"),
      ),
      body: new Center(
          child: new RaisedButton(
              child: new Text("靜態路由接收下一頁返回值"),
              onPressed: () {
                Navigator.of(context)
                    .pushNamed('router/new_page_with_callback')
                    .then((value) {
                  showDialog(
                      context: context,
                      child: new AlertDialog(
                        content: new Text(value),  
                      ));
                });
              })),
    );
  }
}
複製代碼

B頁面代碼:code

從效果圖中能夠看到,當我點擊B頁面中間的按鈕時會把數據回傳給上一頁,可是直接點擊導航欄左上角的返回按鈕回到A頁面時並不會把數據傳遞給上一個頁面,這裏是由於我在B頁面的按鈕上pop頁面出棧的時候把參數放進裏面做爲了參數傳遞,pop()可接收一個Object對象做爲參數傳遞

Navigator.of(context).pop(T extends Object);
複製代碼

這就告訴咱們當咱們須要給上一個頁面回傳數據的時候可直接藉助pop傳遞Navigator.of(context).pop("頁面結束後返回的數據");,不須要傳值的時候直接返回空對象Navigator.of(context).pop()便可。

import 'package:flutter/material.dart';

class StaticNavigatorPageWithResult extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("靜態路由帶返回參數"),
      ),
      body: new Center(
        child: new OutlineButton(
          onPressed: () {
            Navigator.of(context).pop("頁面結束後返回的數據");
          },
          child: Text("點我返回上個頁面結束後返回的數據"),
        ),
      ),
    );
  }
}

複製代碼

3.動態路由跳頁

文章的開頭咱們提到藉助動態路由能夠向下一個頁面傳遞參數,一樣也能夠接收新頁面回傳回來的數據。下面我模擬兩個使用動態路由的場景,既然動態路由能夠傳值那就確定能夠不傳值跳頁,我就不模擬動態路由不傳值跳頁的例子了,讀者藉助靜態路由的樣例自行測試便可,咱們主要講解一下藉助動態路由傳值的例子。

場景三:點擊A頁面中的按鈕,把用戶名跟密碼傳遞給下一個頁面B頁面,B頁面處理完接收到的數據後把結果回傳給A頁面,A頁面中把從B頁面回傳回來的數據顯示在Dialog上。

模擬效果圖

動態路由傳遞參數
使用動態路由時咱們再也不須要像靜態路由那樣在 MaterialApp中的router中提早註冊路由路徑,只須要在使用 Navigator.push傳入MaterialPageRoute對象便可

Navigator.push(
    context,
    new MaterialPageRoute(
        //_表明參數爲空
        builder: (_) => new DynamicNaviattionPage(
              username: "xiedong",
              password: "123456",
            )));
複製代碼

A頁面代碼:

import 'package:flutter/material.dart';
import 'package:flutter_app/pages/simpleWidget/navigator/DynamicNavigationPage.dart';

void main() {
  runApp(new MaterialApp(home: new FlutterDemo()));
}

class FlutterDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Flutter進階之旅"),
        ),
        body: new Center(
            child: new RaisedButton(
          onPressed: () {
            Navigator.push(
                context,
                new MaterialPageRoute(
                    //_表明參數爲空
                    builder: (_) => new DynamicNaviattionPage(
                          username: "xiedong",
                          password: "123456",
                        ))).then((value) {
              showDialog(
                  context: context,
                  child: new AlertDialog(
                    content: new Text(value),
                  ));
            });
          },
          child: new Text("動態路由傳參"),
        )));
  }
}
複製代碼

B頁面代碼:

import 'package:flutter/material.dart';

class DynamicNaviattionPage extends StatelessWidget {
  var username;
  var password;

  DynamicNaviattionPage({Key key, this.username, this.password})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("動態路由"),
      ),
      body: new Center(
        child: new Column(
          children: <Widget>[
            new MaterialButton(
              onPressed: () {
                Navigator.pop(context, "未查詢到改該用戶信息");
              },
              child: new Text("點我返回"),
              color: Colors.lightGreen,
            ),
            new Text("上頁傳遞過來的username $username"),
            new Text("上頁傳遞過來的password $password"),
          ],
        ),
      ),
    );
  }
}
複製代碼

關於路由重點總結

  • Flutter路由分爲靜態路由跟動態路由,靜態路由不支持向下一個頁面傳遞參數,動態路由可傳遞
  • 靜態路由使用時須要提早註冊聲明頁面路徑,
  • 動態路由能夠直接在使用時構造路由對象,不須要提早註冊路徑。
  • 兩種類型都支持接收下一頁面回傳回來的值
相關文章
相關標籤/搜索