Flutter:學會在頁面間傳遞引數

CoorChice發表於2019-04-06

目錄傳送門:《Flutter快速上手指南》先導篇

在 Flutter 中,有一套自己的頁面傳參機制。

我們仍然需要通過 Navigator 來實現頁面間的傳參。

1.如何進行頁面傳參

Flutter 中頁面傳參的思路是,為頁面 Widget 的建構函式中增加引數,通過建構函式來給頁面傳參。

class HomePage extends StatelessWidget {
  final PageData data;

  // 帶所需引數的建構函式
  const HomePage({Key key, this.data}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
      ),
      body: Container(
        color: Colors.white,
        child: Center(
          child: Text(data != null ? data.data : 'There is no data!'),
        ),
      ),
    );
  }
}
複製程式碼

來看看跳轉時如何給他傳引數:

var data = PageData('Come form SplashPage!');
// 使用 Navigator 跳轉頁面
Navigator.push(context, MaterialPageRoute(
        builder: (context) => HomePage(
              data: data,
            )));
複製程式碼

2.如何接收頁面回參

想要頁面能夠接收回,在跳轉的時候,需要在跳轉的時候進行處理:

// 需要使用非同步的方式跳轉,然後等待結果返回
void jumpToHome(BuildContext context) async {
  var data = PageData('Come form SplashPage!');
  // 使用 Navigator 跳轉頁面
  // 使用 await 等待結果返回
  var result = await Navigator.push( context, MaterialPageRoute(
          builder: (context) => HomePage(
                data: data,
              )));
  if (result != null) {
    // 通知狀態變化,更新 ui
    setState(() {
      text = result;
    });
  }
}
複製程式碼

其實,接收頁面回參的方式也很簡單,就是需要在一個非同步函式中非同步跳轉,然後通過 await 等待結果返回。

當然,由於 Navigator.push() 返回的是一個 Future,你也可以在 then() 函式中接收返回引數處理。

Navigator.push( context, MaterialPageRoute(
          builder: (context) => HomePage(
                data: data,
              ))).then((result){ //... });
複製程式碼

在另一個頁面中,返回結果給上一個頁面:

Navigator.pop(context, result);
複製程式碼

就是在 pop 的時候帶上要返回的資訊就可以了。

3.一個完整的傳參、回參例子

建立第一個頁面,splash_page.dart:

class SplashPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _SplashPage();
  }
}

class _SplashPage extends State<SplashPage> {
  final splashUrl =
      'https://raw.githubusercontent.com/chenBingX/img/master/其它/u=343452579,826911251&fm=26&gp=0.jpg';

  var text = 'Next';

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Stack(
      alignment: Alignment(0, 0.75),
      children: <Widget>[
        Container(
          decoration: BoxDecoration(
              image: DecorationImage(image: NetworkImage(splashUrl))),
        ),
        GestureDetector(
          // 設定點選事件
          onTap: () {
            jumpToHome(context);
          },
          child: Container(
              padding: EdgeInsets.only(left: 12, top: 6, right: 12, bottom: 6),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.all(Radius.circular(6)),
                gradient: LinearGradient(
                  colors: <Color>[Colors.red, Colors.green, Colors.blue],
                ),
              ),
              child: Text(
                text,
                style: TextStyle(color: Colors.white, fontSize: 16),
              )),
        ),
      ],
    );
  }

  void jumpToHome(BuildContext context) async {
    var data = PageData('Come form SplashPage!');
    // 使用 Navigator 跳轉頁面
    var result = await Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => HomePage(
                  data: data,
                )));
    if (result != null) {
      setState(() {
        text = result;
      });
    }
  }
}
複製程式碼

建立第二個頁面,home_page.dart :

class HomePage extends StatelessWidget {
  final PageData data;

  // 帶所需引數的建構函式
  const HomePage({Key key, this.data}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
        appBar: AppBar(
          title: Text('Home Page'),
        ),
        body: GestureDetector(
          onTap: () {
            Navigator.pop(context, 'HomePage popped!');
          },
          child: Container(
            color: Colors.white,
            child: Center(
              child: Text(data != null ? data.data : 'There is no data!'),
            ),
          ),
        ));
  }
}
複製程式碼

執行起來,main.dart

void main() => runApp(MaterialApp(
      title: 'Flutter',
      home: SplashPage(),
    ));
複製程式碼

執行效果:

目錄傳送門:《Flutter快速上手指南》先導篇

如何找到我?

傳送門:CoorChice 的主頁

傳送門:CoorChice 的 Github


相關文章