今天給大家講一下MaterialApp應用組件及routes路由詳解,我會著重說一下routes路由的使用及解釋,因為會經常用到,前面我寫的一些demo所涉及到的組件,都是遵循著Material Design設計風格,所謂的Material Design是由Goodle推出的全新的設計語言,這種設計... ...
如需轉載,請註明出處:Flutter學習筆記(15)--MaterialApp應用組件及routes路由詳解
最近一段時間生病了,整天往醫院跑,也沒狀態學東西了,現在是好了不少了,也該繼續學習啦!!!
今天給大家講一下MaterialApp應用組件及routes路由詳解,我會著重說一下routes路由的使用及解釋,因為會經常用到,前面我寫的一些demo所涉及到的組件,都是遵循著Material Design設計風格,所謂的Material Design是由Goodle推出的全新的設計語言,這種設計旨在為手機、平板電腦、台式機和其他平臺更一致、更廣泛的外觀和感覺,接下來我們看一下常見的Material Design風格組件:
組件名稱 | 中文名稱 | 簡單說明 |
Appbar | 應用按鈕組件 | 應用的工具按鈕 |
AlertDialog | 對話框組件 | 有操作按鈕的對話框 |
BottomNavigationBar | 底部導航組件 | 底部導航條,可以很容易的在tab之間切換和瀏覽頂級試圖 |
Card | 卡片組件 | 帶有邊框陰影的卡片組件 |
Drawer | 抽屜組件 | Drawer抽屜組件可以實現類似抽屜拉開關閉的效果 |
FloatingActionButton | 懸浮按鈕組件 | 應用的主要功能操作按鈕 |
FlatButton | 扁平按鈕組件 | 扁平化風格的按鈕 |
MaterialApp | Material應用組件 | MaterialApp代表使用紙墨設計風格的應用 |
PopupMenuButton | 彈出菜單組件 | 彈出菜單按鈕 |
Scaffold | 腳手架組件 | 實現了基本的Material Design佈局 |
SnackBar | 輕量提示組件 | 一個輕量消息提示組件,在屏幕的底部顯示 |
SimpileDialog | 簡單對話框組件 | 簡單對話框組件。只起提示作用,沒有交互 |
TabBar | 水平選項卡及視圖組件 | 一個顯示水平選項卡的Material Design組件 |
TextField | 文本框組件 | 可以接受應用輸入文本的組件 |
Material Design風格的組件有這麼多,不看不知道,一看嚇一跳,這基本上都沒有用過呀,漫漫長征路,還有很遠要走呀,一個一個學吧!!!
-
MaterialApp(應用組件)
屬性名 | 類型 | 說明 |
title | String | 應用程式的標題,該標題出現在如下位置Android:任務管理器的程式快照之上,iOS:程式切換管理器中 |
theme | ThemeData | 定義應用所使用的主題顏色,可以制定一個主題中每個控制項的顏色 |
color | Color | 應用的主要顏色值,即primary color |
home | Widget | 這個是一個Widget對象,用來定義一個主題中每個控制項的顏色 |
routes | Map<String,WidgetBuilder> | 定義應用中頁面跳轉的原則 |
initialRoute | String | 初始化路由 |
onGenerateRoute | RouteFactory | 路由回調函數,當通過Nacigator.of(context).pushNamed跳轉路由時,在routes查找不到時,會調用該方法 |
onLocaleChanged | 當系統需改語言的時候,會觸發這個回調 | |
nagavitorObserver | List<NavigatorObserver> | 導航觀察器 |
debugShowMaterialGird | bool | 是否顯示紙墨設計基礎佈局網格,用來調試UI的工具 |
showPerformanceOverlay | bool | 顯示性能標簽 |
具體看下代碼應用:
import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; void main() => runApp(DemoApp()); class DemoApp extends StatelessWidget{ //這個是整個應用的主組件 @override Widget build(BuildContext context) { // TODO: implement build return new MaterialApp( title: 'MaterialApp示例', debugShowMaterialGrid: true, showPerformanceOverlay: true, theme: new ThemeData( primaryColor: Colors.deepOrange ), home: new MaterialAppDemo(), ); } } class MaterialAppDemo extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return new Scaffold( appBar: new AppBar( title: Text('MaterialAppDemo'), ), body: new Center( child: new Text('MaterialAppDemo'), ), ); } }
效果圖:
demo裡面我主要嘗試了title、theme、home、debugShowMaterialGird、showPerformanceOverlay屬性,根據截圖,給大家直觀的對比一下結果:
title:應用程式的標題(因為我只有Android測試機),可以看到第二張截圖,切到任務管理器,應用程式的標題為MaterialApp示例。
theme:我用theme更改了應用主題的顏色,可以看到第一張截圖導航欄的顏色改為了橙色。
home:home代表著整個頁面的主widget,可以理解為根widget,而home的主體就是一個Center容器組件,然後裡面放一個文本。
debugShowMaterialGird:這個屬性我們設置為了true,頁面展示出來會有很多網格,用於調試UI(這個要怎麼用來調試UI,小弟還不會。。。)
showPerformanceOverlay:性能標簽,這個設置為true,在頁面的最上方會出現一些性能相關的數據。
-
routes(路由處理)
routes對象是一個Map<String,WidgetBuilder>,當使用Navigator.pushName來路由的時候,會在routes查找路由的名字,然後使用對應的WidgetBuilder來構造一個帶有頁面切換動畫的MaterialPageRoute。
下麵我著重講一下routes路由處理,因為我覺得頁面間的跳轉是最常用到的,而且很重要,下麵的demo主要功能是在A頁面點擊一個按鈕跳轉到B頁面,並且兩個頁面間傳值。
註:路由跳轉分靜態路由跳轉和動態路由跳轉,兩者的區別就是是否給第二個頁面傳值
import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; void main() => runApp(DemoApp()); class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return new MaterialApp( title: 'theme Title', debugShowMaterialGrid: false, home: new Scaffold( appBar: new AppBar( leading: Icon(Icons.menu), actions: <Widget>[ Icon(Icons.search) ], title: new Text('routes demo'), ), body: new Center( child: new Text('主頁'), ), ), routes: { '/first':(BuildContext context) => new FirstPage(), '/second':(BuildContext context) => new SecondPage(""), }, initialRoute: '/first',//初始化路由為first頁面 ); } } class FirstPage extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return new Scaffold( appBar: new AppBar( title: new Text('First Page'), ), body: new Center( child: RaisedButton( child: new Text('第一個頁面'), onPressed: (){ //靜態路由跳轉,不給第二個頁面傳值 // Navigator.pushNamed(context, '/second').then((value){ // Fluttertoast.showToast(msg: value,toastLength: Toast.LENGTH_LONG,gravity: ToastGravity.BOTTOM); // }); //動態路由跳轉,給第二個頁面傳值 Navigator.of(context).push(new MaterialPageRoute(builder: (context){ return new SecondPage('這是從第一個頁面傳遞出去的數據'); })).then((value){ Fluttertoast.showToast(msg: value,toastLength: Toast.LENGTH_LONG,gravity: ToastGravity.BOTTOM); }); } ), ), ); } } class SecondPage extends StatelessWidget { var content = ''; SecondPage(this.content); @override Widget build(BuildContext context) { // TODO: implement build return new Scaffold( appBar: new AppBar( title: new Text('Second Page'), ), body: new RaisedButton( child: new Text(content), onPressed: (){ // Navigator.pop(context);//不給上一級頁面返回參數 Navigator.of(context).pop("這個是從第二個頁面返回的數據");//給上一級頁面返回參數 } ), ); } }
效果截圖:
來細講一下上面的代碼吧,要不然還真容易看懵逼了。
1.首先初始化路由列表,為後面頁面跳轉做準備,路由列表對應這每一個頁面
routes: { '/first':(BuildContext context) => new FirstPage(), '/second':(BuildContext context) => new SecondPage(""), },
2.靜態路由跳轉,靜態由A頁面跳轉到B頁面,不給B頁面傳值,但是接收B頁面返回的數據,並將返回值toast出來,即圖3
Navigator.pushNamed(context, '/second').then((value){ Fluttertoast.showToast(msg: value,toastLength: Toast.LENGTH_LONG,gravity: ToastGravity.BOTTOM); });
3.動態路由跳轉,A頁面跳轉到B頁面,並給B頁面傳值,將B頁面的按鈕文案賦值,從B頁面返回後,將B頁面的返回值toast出來,即圖2,圖3
Navigator.of(context).push(new MaterialPageRoute(builder: (context){ return new SecondPage('這是從第一個頁面傳遞出去的數據'); })).then((value){ Fluttertoast.showToast(msg: value,toastLength: Toast.LENGTH_LONG,gravity: ToastGravity.BOTTOM); });
4.由B頁面帶數據返回到A頁面(頁面Pop返回有兩類,一類帶參數返回,一類不帶參數返回)
4.1帶參數返回
Navigator.of(context).pop("這個是從第二個頁面返回的數據");//給上一級頁面返回參數
4.2不帶參數返回
Navigator.pop(context);//不給上一級頁面返回參數
註:頁面Pop還有兩個方法常用到
Navigator.canPop(context);//頁面是否可以pop,返回bool值,可以用作頁面判斷 Navigator.maybePop(context);//如果當前頁面可以pop,則會執行,反之則不會執行,更安全
以上就是今天的全部內容了,稍微難一點的就是路由這塊兒了,我寫的demo還是很簡單的,頁面跳轉傳值只是字元串,在項目中還會遇到其他類型的數據參數,暫時就先不研究了,等用到的時候在具體細看吧,上面的內容,如果各位有任何疑問,或者發現有錯誤的地方,還望留言!!!