【Flutter】三十一、Flutter路由

Flutter中使用Navigator可以完成路由的路由的跳轉。

一、Navigator

1.1 Navigator的使用

  • 首先創建兩個頁面:
    main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter demo')
        ),
        body: RouteDemo(),
      ),
    );
  }
}

class RouteDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Center(
      child: RaisedButton(
        child: Text('打開新的路由'),
        onPressed: () {},
      ),
    );
  }
}

page.dart:

import 'package:flutter/material.dart';

class PageRouteDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('pageRoute'),
        leading: IconButton(
            icon: Icon(Icons.arrow_back),
            onPressed: () {
            }),
      ),
      body: Center(
        child: Text('pageRoute'),
      ),
    );
  }
}
  • 要實現從main.dart跳轉至page.dart,需藉助Navigator,現在對main.dart中的按鈕點擊事件中添加如下代碼:
// 頁面入棧
Navigator.push(context, MaterialPageRoute(
	builder: (context) => PageRouteDemo()));
  • 現在點擊按鈕,就可以跳轉到page.dart頁面了,但是我們點擊page.dart上方的返回按鈕是沒有反應的,此時我們在page.dart中的返回圖標中添加點擊事件:
// 頁面出棧
Navigator.pop(context);

在這裏插入圖片描述

1.2 使用Navigator傳遞參數

    在頁面跳轉時,難免會傳遞一些參數,那麼使用Navigator怎樣傳遞參數呢。這裏有兩種方法,其中一種是通過PageRouteDemo的構造函數傳遞,另一種是通過設置MaterialPageRoute中的settings屬性。:

import 'package:flutter/material.dart';

class PageRouteDemo extends StatelessWidget {
  String param;
  PageRouteDemo({this.param});
  
  @override
  Widget build(BuildContext context) {
  	// 獲取來自settings屬性的數據
  	Map map = ModalRoute.of(context).settings.arguments;
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('pageRoute'),
        leading: IconButton(
            icon: Icon(Icons.arrow_back),
            onPressed: () {
              Navigator.pop(context);
            }),
      ),
      body: Center(
        child: Text('通過構造函數傳遞: $param;settings參數傳遞:${map["id"]}'),
      ),
    );
  }
}
Navigator.push(context, MaterialPageRoute(
	builder: (context) => PageRouteDemo('來自上個頁面的數據'),
	settings: RouteSettings(arguments: {"id": 2123})
));

    在調用Navigator.push時直接將參數傳入PageRouteDemo構造函數當中即可。那麼如果是返回的時候要傳遞數據呢?其實Navigator.pop是可以傳入第二個參數,這個參數就是當前頁面要返回給上一個頁面的數據,然後在上個頁面使用Navigator.push接受這個數據。

Navigator.pop(context, '頁面返回時傳遞的數據');

main.dart中接受數據:

	RaisedButton(
        child: Text('打開新的路由'),
        onPressed: () async {
          String result = await Navigator.push(
              context,
              MaterialPageRoute(
                  builder: (context) => PageRouteDemo(param:'來自上個頁面的數據'),
                  // fullscreenDialog: false,
                  settings: RouteSettings()));
          if (result != null) {
            Scaffold.of(context).showSnackBar(SnackBar(
              content: Text(result),
            ));
          }
        },
      ),

在這裏插入圖片描述

二、MaterialPageRoute

    MaterialPageRoute繼承自PageRoute類,PageRoute類是一個抽象類,表示佔有整個屏幕空間的一個模態路由頁面,它還定義了路由構建及切換時過渡動畫的相關接口及屬性。MaterialPageRoute 是Material組件庫的一個Widget,它可以針對不同平臺,實現與平臺頁面切換動畫風格一致的路由切換動畫:

  • Andriod:當打開新頁面時,頁面會從底部滑動到頂部。
  • iOS:當打開新頁面時,頁面會從右側滑動進入屏幕。

2.1 MaterialPageRoute構造函數

MaterialPageRoute({
    @required this.builder, // 是一個WidgetBuilder類型的回調函數,它的作用是構建路由頁面的具體內容,返回值是一個widget
    RouteSettings settings, // 包含路由的配置信息,如路由名稱、是否初始路由(首頁)
    this.maintainState = true, // 默認情況下,當入棧一個新路由時,原來的路由任然會被保存在內存中,如果想在路由沒用的時候釋放其所佔用的所有資源,可以設置maintainState爲false
    bool fullscreenDialog = false, //表示新的路由頁面是否是一個全屏的模態對話框,在iOS中,如果fullscreenDialog爲true,新頁面將會從屏幕底部滑入
  })

三、命名路由

    通過MaterialApp中的routes屬性註冊一個路由表,調用Navigator.pushNamed方法指定要跳轉的路由,同樣可以實現頁面跳轉。示例代碼如下:

void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: {
        '/page': (context) => PageRouteDemo()
      },
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter demo')
        ),
        body: RouteDemo(),
      ),
    );
  }
}

class RouteDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Center(
      child: RaisedButton(
        child: Text('打開新的路由'),
        onPressed: () {
          Navigator.pushNamed(context, '/page', arguments: {'id': 324});
        },
      ),
    );
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章