一、概述
上篇文章介紹 MaterialApp 、Scaffold ,但是沒(méi)有內(nèi)容比較多,沒(méi)有介紹完畢。本篇文章繼續(xù)上文繼續(xù)說(shuō)明。
二、 Scaffold Widget 補(bǔ)充
bottomNavigationBar 是 Scaffold 的屬性,用來(lái)設(shè)置應(yīng)用程序的底部應(yīng)用或?qū)Ш綑?,其是一個(gè) Widget ,通常使用 BottomAppBar 或 BottomNavigationBar 。主要用來(lái)顯示消息以及提供特定功能的導(dǎo)航。
BottomAppBar 是一個(gè)頂部可以有凹口的 Widget ,是一個(gè) StatefulWidget 。通常與 FloatingActionButton 一起使用。其構(gòu)造方法如下:
const BottomAppBar({
Key key,
//Color類(lèi)型可選命名參數(shù),底部程序欄的背景色
this.color,
//double類(lèi)型可選命名參數(shù),相對(duì)于其父應(yīng)用程序欄放置底部應(yīng)用程序欄的z坐標(biāo)
this.elevation,
//NotchedShape類(lèi)型可選命名參數(shù),為浮動(dòng)操作按鈕制作的凹槽
this.shape,
//Clip類(lèi)型可選命名參數(shù),設(shè)置內(nèi)容裁剪方式
this.clipBehavior = Clip.none,
//double類(lèi)型可選命名參數(shù),浮動(dòng)動(dòng)作按鈕和底部應(yīng)用欄的凹口之間的邊距
this.notchMargin = 4.0,
//Widget類(lèi)型可選命名參數(shù),要顯示的Widget
this.child,
})
使用如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyFirstPage(),
);;
}
}
class MyFirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page 1"),
),
body: Container(
color: Colors.yellow,
child: Center(child: Text("主體內(nèi)容"),),
),
endDrawer: Drawer(),
bottomNavigationBar: BottomAppBar(
color: Colors.deepPurpleAccent,
child: Text("底部BottomAppBar"),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
print("點(diǎn)擊");
},
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}
如果不提供 BottomAppBar 的 child 設(shè)置,不會(huì)拋出異常,但是不會(huì)顯示 BottomAppBar 。
本例的效果如下:

如果想要設(shè)置 BottomAppBar 的高度,可以通過(guò)嵌套使用帶有高度的 Widget ,如下使用 Container :
class MyFirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page 1"),
),
body: Container(
color: Colors.yellow,
child: Center(child: Text("主體內(nèi)容"),),
),
endDrawer: Drawer(),
bottomNavigationBar: BottomAppBar(
color: Colors.deepPurpleAccent,
child: Container(
child: Text("底部BottomAppBar"),
height: 50.0,
),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
print("點(diǎn)擊");
},
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}

使用有凹口的 BottomAppBar 需要 shape 和 FloatingActionButtonLocation.centerDocked 或 FloatingActionButtonLocation.endDocked 配合使用。如下:
class MyFirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page 1"),
),
body: Container(
color: Colors.yellow,
child: Center(child: Text("主體內(nèi)容"),),
),
endDrawer: Drawer(),
bottomNavigationBar: BottomAppBar(
color: Colors.deepPurpleAccent,
shape: const CircularNotchedRectangle(),
child: Container(
height: 50.0,
),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
print("點(diǎn)擊");
},
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
}
效果如下圖:

BottomAppBar 中也可以顯示多個(gè) Widget ,需要使用 Row 橫向布局 Widget 容器,后面會(huì)詳細(xì)介紹 Row 。使用如下:
class MyFirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page 1"),
),
body: Container(
color: Colors.yellow,
child: Center(child: Text("主體內(nèi)容"),),
),
endDrawer: Drawer(),
bottomNavigationBar: BottomAppBar(
color: Colors.deepPurpleAccent,
shape: const CircularNotchedRectangle(),
child: Container(
child: Row(
children: <Widget>[
IconButton(icon: Icon(Icons.print), onPressed: (){}),
IconButton(icon: Icon(Icons.add), onPressed: (){}),
IconButton(icon: Icon(Icons.add_a_photo), onPressed: (){}),
],
),
height: 50.0,
),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
print("點(diǎn)擊");
},
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
}
效果如下圖:

BottomNavigationBar 主要用于應(yīng)用的底部導(dǎo)航,繼承自 StatefulWidget ,為有狀態(tài)的 Widget ,構(gòu)造函數(shù)如下:
BottomNavigationBar({
Key key,
//List<BottomNavigationBarItem>類(lèi)型必傳參數(shù),底部導(dǎo)航欄中的選項(xiàng)
@required this.items,
//ValueChanged<int>類(lèi)型可選命名參數(shù),點(diǎn)擊某個(gè)選項(xiàng)時(shí)的回調(diào)函數(shù)
this.onTap,
//int類(lèi)型可選命名參數(shù),當(dāng)前被選擇的選項(xiàng)索引
this.currentIndex = 0,
//double類(lèi)型可選命名參數(shù),此底部導(dǎo)航欄的z坐標(biāo)。
this.elevation = 8.0,
//BottomNavigationBarType類(lèi)型可選命名參數(shù),定義底部導(dǎo)航欄的布局和行為
BottomNavigationBarType type,
//Color類(lèi)型可選命名參數(shù),被選擇的選項(xiàng)的顏色,get屬性
Color fixedColor,
//Color類(lèi)型可選命名參數(shù),底部導(dǎo)航欄背景色
this.backgroundColor,
//double類(lèi)型可選命名參數(shù),底部導(dǎo)航中的圖標(biāo)的大小
this.iconSize = 24.0,
//Color類(lèi)型可選命名參數(shù),所選底部導(dǎo)航圖標(biāo)和底部導(dǎo)航圖標(biāo)標(biāo)簽的顏色
Color selectedItemColor,
//Color類(lèi)型可選命名參數(shù),未選擇的底部導(dǎo)航圖標(biāo)和底部導(dǎo)航圖標(biāo)標(biāo)簽的顏色
this.unselectedItemColor,
//IconThemeData類(lèi)型可選命名參數(shù),當(dāng)前選定的底部導(dǎo)航圖標(biāo)中圖標(biāo)的大小、不透明度和顏色
this.selectedIconTheme = const IconThemeData(),
//IconThemeData類(lèi)型可選命名參數(shù),當(dāng)前未選中的底部導(dǎo)航圖標(biāo)中圖標(biāo)的大小、不透明度和顏色
this.unselectedIconTheme = const IconThemeData(),
//double類(lèi)型可選命名參數(shù),選擇時(shí)底部導(dǎo)航項(xiàng)標(biāo)簽的字體大小
this.selectedFontSize = 14.0,
//double類(lèi)型可選命名參數(shù),未選擇時(shí)底部導(dǎo)航項(xiàng)標(biāo)簽的字體大小
this.unselectedFontSize = 12.0,
//TextStyle類(lèi)型可選命名參數(shù),選擇時(shí)底部導(dǎo)航項(xiàng)標(biāo)簽的文本樣式。
this.selectedLabelStyle,
//TextStyle類(lèi)型可選命名參數(shù),未選擇時(shí)底部導(dǎo)航項(xiàng)標(biāo)簽的文本樣式。
this.unselectedLabelStyle,
//bool類(lèi)型可選命名參數(shù),是否為選擇的底部導(dǎo)航圖標(biāo)顯示標(biāo)簽文本
this.showSelectedLabels = true,
//bool類(lèi)型可選命名參數(shù),是否為未選定的底部導(dǎo)航項(xiàng)顯示標(biāo)簽文本
bool showUnselectedLabels,
})
BottomNavigationBarItem 為帶有圖標(biāo)和標(biāo)題的交互式按鈕,通常與 BottomNavigationBar 一起使用,構(gòu)造方法如下:
const BottomNavigationBarItem({
//Widget類(lèi)型必傳參數(shù),底部導(dǎo)航選項(xiàng)的圖標(biāo)
@required this.icon,
//Widget類(lèi)型可選命名參數(shù),底部導(dǎo)航選項(xiàng)的標(biāo)題
this.title,
//Widget類(lèi)型可選命名參數(shù),選擇底部導(dǎo)航選項(xiàng)的替代圖標(biāo)。當(dāng)選項(xiàng)被選擇時(shí)將使用此設(shè)置的圖標(biāo),如果不為null
Widget activeIcon,
//Color類(lèi)型可選命名參數(shù),底部導(dǎo)航欄的背景徑向動(dòng)畫(huà)的顏色。只有當(dāng)設(shè)置BottomNavigationBarType.shifting
//時(shí)才生效,點(diǎn)擊后底部導(dǎo)航背景色將變化為此色
this.backgroundColor,
})
使用方法如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyRootNavigationPage(),
);;
}
}
class MyRootNavigationPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return _MyRootNavigationPage();
}
}
class _MyRootNavigationPage extends State<MyRootNavigationPage> {
final List<String> _pageTitles = <String>[
"page 1",
"page 2",
"page 3"
];
String _pageTitle;
int _currentSelected = 0;
final List<Widget> _pageWidget = <Widget>[
_FirstPage(),
_SecondPage(),
_ThirdPage(),
];
_itemSelected(int valueIndex) {
setState(() {
_currentSelected = valueIndex;
_pageTitle = _pageTitles.elementAt(valueIndex);
});
}
@override
void initState() {
super.initState();
_pageTitle = _pageTitles.first;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("$_pageTitle"),
),
body: Container(
child: _pageWidget.elementAt(_currentSelected),
),
endDrawer: Drawer(),
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.print),
title: Text("Page1"),
),
BottomNavigationBarItem(
icon: Icon(Icons.party_mode),
title: Text("Page2"),
),
BottomNavigationBarItem(
icon: Icon(Icons.add_a_photo),
title: Text("Page3"),
),
],
currentIndex: _currentSelected,
onTap: _itemSelected,
backgroundColor: Colors.yellowAccent,
selectedItemColor: Colors.red,
unselectedItemColor: Colors.black45,
),
);
}
}
class _FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text("Page 1"));
}
}
class _SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text("Page 2"));
}
}
class _ThirdPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text("Page 3"));
}
}
對(duì)于 BottomNavigationBarItem 內(nèi)的顯示圖標(biāo),可以使用 Image 加載自定義的圖片。上述代碼效果如下:

BottomNavigationBar 的 type 為 BottomNavigationBarType 類(lèi)型,是一個(gè)枚舉類(lèi)型,如下:
enum BottomNavigationBarType {
//底部導(dǎo)航條的底部導(dǎo)航條有固定的寬度
fixed,
//底部導(dǎo)航欄底部導(dǎo)航欄的位置和大小動(dòng)畫(huà)和標(biāo)簽在被點(diǎn)擊時(shí)淡入
shifting,
}
Scaffold 的 persistentFooterButtons 為 List<Widget> 類(lèi)型,是一組顯示在 Scaffold 底部的 Widget ,通常使用 FlatButton 。這組 Widget 會(huì)呈現(xiàn)在 bottomNavigationBar 的上方,body 下方。他們是持續(xù)可見(jiàn)的,即使 body 進(jìn)行滾動(dòng)依然如此。使用方式如下:
persistentFooterButtons: <Widget>[
FlatButton(onPressed: (){}, child: Text("按鈕1")),
FlatButton(onPressed: (){}, child: Text("按鈕1")),
FlatButton(onPressed: (){}, child: Text("按鈕1"))
],
效果如下圖:

bottomSheet 對(duì)應(yīng)的是一個(gè) Widget ,是一個(gè)始終可見(jiàn)的 Widget ??梢杂脕?lái)定義底部的菜單或?qū)υ?huà)框。也可以使用 Flutter 提供好的
使用任意 Widget 的方法如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyFirstPage(),
);;
}
}
class MyFirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page 1"),
),
body: Container(
color: Colors.yellow,
child: Center(child: Text("主體內(nèi)容"),),
),
bottomSheet: Container( //bottomSheet
color: Colors.red,
height: 80,
child: Center(child: Text("BottomSheet")),
),
endDrawer: Drawer(),
);
}
}
效果如下圖:

在底部展示消息還可以使用 SnackBar Widget ,其是一個(gè) StatefulWidget ,是一個(gè)輕量級(jí)的帶有可選操作的在屏幕底部暫時(shí)出現(xiàn)的 Widget。其構(gòu)造方法如下:
const SnackBar({
Key key,
//Widget類(lèi)型必傳參數(shù),要顯示的Widget
@required this.content,
//Color類(lèi)型可選命名參數(shù),用于指定背景色
this.backgroundColor,
//double類(lèi)型可選命名參數(shù),SnackBar的z坐標(biāo),這可以控制SnackBar下方陰影的大小
this.elevation,
//ShapeBorder類(lèi)型可選命名參數(shù),SnackBar的形狀
this.shape,
//SnackBarBehavior類(lèi)型可選命名參數(shù),用于設(shè)置SnackBar的行為和位置
this.behavior,
//SnackBarAction類(lèi)型可選命名參數(shù),要執(zhí)行的行為
this.action,
//Duration類(lèi)型可選命名參數(shù),SnackBar的持續(xù)顯示時(shí)間
this.duration = _snackBarDisplayDuration,
//Animation<double>類(lèi)型可選命名參數(shù),動(dòng)畫(huà)
this.animation,
//VoidCallback類(lèi)型可選命名參數(shù),第一次在Scaffold中出現(xiàn)時(shí)的回調(diào)函數(shù)
this.onVisible,
})
使用如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyFirstPage(),
);;
}
}
class MyFirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page 1"),
),
body: Builder(
builder: (BuildContext context){
return Container(
color: Colors.yellow,
child: Center(
child: RaisedButton(
child: Text("SnackBar"),
onPressed: (){
ScaffoldState state = Scaffold.of(context);
SnackBar snBar = SnackBar(
content: Text("這是一個(gè)提示信息"),
backgroundColor: Colors.deepPurpleAccent,
action: SnackBarAction(
label: "點(diǎn)擊查看詳情",
onPressed: (){
print("詳情內(nèi)容");
},
),
onVisible: ()=> print("第一次出現(xiàn)執(zhí)行,僅執(zhí)行一次"),
);
state.showSnackBar(snBar);
},
),
),
);
},
),
endDrawer: Drawer(),
);
}
}
效果如下:

三、MaterialApp Widget 補(bǔ)充
MaterialApp 中的 theme 和 darkTheme 均是 ThemeData 類(lèi)型,用于設(shè)置應(yīng)用的主題顏色和板式值??梢耘渲?Theme 或 MaterialApp Widget ,獲取當(dāng)前的主題,可以使用 Theme.of 。區(qū)別在于 darkTheme 意思是提供暗黑模式的主題,在設(shè)置 ThemeData 的 Brightness 時(shí)應(yīng)設(shè)置為 dark 。如果同時(shí)提供 theme 和 darkTheme ,則可以設(shè)置 themeMode 進(jìn)行主題選擇,這就是同時(shí)提供兩種主題模式的用途,可以通過(guò)不同的設(shè)置提供不同的主題樣式。主題主要用來(lái)定義應(yīng)用程序通用的樣式和顏色基調(diào),可以再對(duì)不同的 Widget 做具體細(xì)節(jié)調(diào)整。其構(gòu)工廠(chǎng)造函數(shù)如下:
factory ThemeData({
//Brightness類(lèi)型可選命名參數(shù),用于設(shè)置主題的模式,dark或者light
Brightness brightness,
//MaterialColor類(lèi)型可選命名參數(shù),用于定義一種單一的顏色,此顏色帶有始終色調(diào)的顏色樣本
MaterialColor primarySwatch,
//Color類(lèi)型可選命名參數(shù),用于設(shè)置工具欄、標(biāo)簽欄等的背景色
Color primaryColor,
//Brightness類(lèi)型可選命名參數(shù),在主題模式不變的情況下設(shè)置基色(工具欄等)的文本和圖標(biāo)反色
Brightness primaryColorBrightness,
//Color類(lèi)型可選命名參數(shù),原色的較輕版本
Color primaryColorLight,
//Color類(lèi)型可選命名參數(shù),原色的較暗版本
Color primaryColorDark,
//Color類(lèi)型可選命名參數(shù),小部件的前景色(旋鈕、文本、過(guò)卷邊緣效果等)
Color accentColor,
//Brightness類(lèi)型可選命名參數(shù),用于確定放置在強(qiáng)調(diào)色頂部的文本和圖標(biāo)的顏色(例如,浮動(dòng)操作按鈕上的圖標(biāo))
Brightness accentColorBrightness,
//Color類(lèi)型可選命名參數(shù),畫(huà)布顏色
Color canvasColor,
//Color類(lèi)型可選命名參數(shù),Scaffold的頁(yè)面背景色
Color scaffoldBackgroundColor,
//Color類(lèi)型可選命名參數(shù),底部應(yīng)用欄的默認(rèn)顏色
Color bottomAppBarColor,
//Color類(lèi)型可選命名參數(shù),Card的顏色
Color cardColor,
//Color類(lèi)型可選命名參數(shù),分隔線(xiàn)和彈出窗口的顏色也用于列表間、數(shù)據(jù)表中的行間等等
Color dividerColor,
//Color類(lèi)型可選命名參數(shù),使用的焦點(diǎn)顏色表示組件具有輸入焦點(diǎn)
Color focusColor,
//Color類(lèi)型可選命名參數(shù),用于指示指針何時(shí)懸停在組件上的懸停顏色
Color hoverColor,
//Color類(lèi)型可選命名參數(shù),高亮顏色
Color highlightColor,
//Color類(lèi)型可選命名參數(shù),InkWell顏色
Color splashColor,
//InteractiveInkFeatureFactory類(lèi)型可選命名參數(shù),定義墨水池和墨水響應(yīng)產(chǎn)生的墨水飛濺的外觀(guān)
InteractiveInkFeatureFactory splashFactory,
//Color類(lèi)型可選命名參數(shù),用于突出顯示選定行的顏色
Color selectedRowColor,
//Color類(lèi)型可選命名參數(shù),處于非活動(dòng)(但已啟用)狀態(tài)的小部件所用的顏色
Color unselectedWidgetColor,
//Color類(lèi)型可選命名參數(shù),不工作的小部件所用的顏色,與它們的狀態(tài)無(wú)關(guān)
Color disabledColor,
//Color類(lèi)型可選命名參數(shù),“凸起”按鈕中使用的材料的默認(rèn)填充顏色
Color buttonColor,
//ButtonThemeData類(lèi)型可選命名參數(shù),定義按鈕小部件的默認(rèn)配置,如上升按鈕和平板按鈕
ButtonThemeData buttonTheme,
//ToggleButtonsThemeData類(lèi)型可選命名參數(shù),定義ToggleButtons小部件的默認(rèn)配置
ToggleButtonsThemeData toggleButtonsTheme,
//Color類(lèi)型可選命名參數(shù),當(dāng)有選定行時(shí),分頁(yè)數(shù)據(jù)表的標(biāo)題顏色
Color secondaryHeaderColor,
//Color類(lèi)型可選命名參數(shù),文本字段中文本選擇的顏色,如文本字段
Color textSelectionColor,
//Color類(lèi)型可選命名參數(shù),TextField(如文本字段)等中光標(biāo)的顏色
Color cursorColor,
//Color類(lèi)型可選命名參數(shù),用于調(diào)整當(dāng)前所選文本部分的手柄顏色
Color textSelectionHandleColor,
//Color類(lèi)型可選命名參數(shù),與原色形成對(duì)比的顏色,例如用作進(jìn)度條的剩余部分
Color backgroundColor,
//Color類(lèi)型可選命名參數(shù),對(duì)話(huà)框元素的背景顏色
Color dialogBackgroundColor,
//Color類(lèi)型可選命名參數(shù),標(biāo)簽欄中所選標(biāo)簽指示器的顏色
Color indicatorColor,
//Color類(lèi)型可選命名參數(shù),用于提示文本或占位符文本的顏色,例如在文本字段中
Color hintColor,
//Color類(lèi)型可選命名參數(shù),用于輸入驗(yàn)證錯(cuò)誤的顏色,例如在文本字段中
Color errorColor,
//Color類(lèi)型可選命名參數(shù),用于突出顯示可切換小部件(如開(kāi)關(guān)、收音機(jī)和復(fù)選框)活動(dòng)狀態(tài)的顏色
Color toggleableActiveColor,
//String類(lèi)型可選命名參數(shù),用于設(shè)置字體名稱(chēng)
String fontFamily,
//TextTheme類(lèi)型可選命名參數(shù),文字顏色與卡片和畫(huà)布顏色
TextTheme textTheme,
//TextTheme類(lèi)型可選命名參數(shù),與原色形成對(duì)比的文本主題
TextTheme primaryTextTheme,
//TextTheme類(lèi)型可選命名參數(shù),與強(qiáng)調(diào)色形成對(duì)比的文本主題
TextTheme accentTextTheme,
//InputDecorationTheme類(lèi)型可選命名參數(shù),輸入編輯器、文本字段和文本表單字段的默認(rèn)輸入配置值基于此主題
InputDecorationTheme inputDecorationTheme,
//IconThemeData類(lèi)型可選命名參數(shù),與卡片和畫(huà)布顏色形成對(duì)比的圖標(biāo)主題
IconThemeData iconTheme,
//IconThemeData類(lèi)型可選命名參數(shù),與原色形成對(duì)比的圖標(biāo)主題
IconThemeData primaryIconTheme,
//IconThemeData類(lèi)型可選命名參數(shù),與強(qiáng)調(diào)色形成對(duì)比的圖標(biāo)主題
IconThemeData accentIconTheme,
//SliderThemeData類(lèi)型可選命名參數(shù),用于渲染滑塊的顏色和形狀
SliderThemeData sliderTheme,
//TabBarTheme類(lèi)型可選命名參數(shù),用于自定義標(biāo)簽欄指示器的大小、形狀和顏色的主題
TabBarTheme tabBarTheme,
//TooltipThemeData類(lèi)型可選命名參數(shù),用于自定義工具提示視覺(jué)屬性的主題
TooltipThemeData tooltipTheme,
//CardTheme類(lèi)型可選命名參數(shù),用于渲染卡片的顏色和樣式
CardTheme cardTheme,
//ChipThemeData類(lèi)型可選命名參數(shù),用于渲染芯片的顏色和樣式
ChipThemeData chipTheme,
//TargetPlatform類(lèi)型可選命名參數(shù),材料部件應(yīng)適應(yīng)目標(biāo)的平臺(tái)
TargetPlatform platform,
//MaterialTapTargetSize類(lèi)型可選命名參數(shù),配置某些材質(zhì)小部件的命中測(cè)試大小
MaterialTapTargetSize materialTapTargetSize,
//bool類(lèi)型可選命名參數(shù),在材質(zhì)表面應(yīng)用半透明疊加顏色,以指示深色主題的高度
bool applyElevationOverlayColor,
//PageTransitionsTheme類(lèi)型可選命名參數(shù),每個(gè)目標(biāo)平臺(tái)的默認(rèn)材質(zhì)頁(yè)面輸出轉(zhuǎn)換
PageTransitionsTheme pageTransitionsTheme,
//AppBarTheme類(lèi)型可選命名參數(shù),用于自定義應(yīng)用欄的顏色、高度、亮度、圖標(biāo)主題和文本主題的主題
AppBarTheme appBarTheme,
//BottomAppBarTheme類(lèi)型可選命名參數(shù),用于自定義底部工具欄的形狀、高度和顏色的主題
BottomAppBarTheme bottomAppBarTheme,
//ColorScheme類(lèi)型可選命名參數(shù),一組十三種顏色,可用于配置大多數(shù)組件的顏色屬性
ColorScheme colorScheme,
//DialogTheme類(lèi)型可選命名參數(shù),用于自定義對(duì)話(huà)框形狀的主題
DialogTheme dialogTheme,
//FloatingActionButtonThemeData類(lèi)型可選命名參數(shù),用于自定義浮動(dòng)動(dòng)作按鈕的形狀、高度和顏色的主題
FloatingActionButtonThemeData floatingActionButtonTheme,
//Typography類(lèi)型可選命名參數(shù),用于配置文本主題、主文本主題和重音文本主題的顏色和幾何文本主題值
Typography typography,
//CupertinoThemeData類(lèi)型可選命名參數(shù),要從“材料”主題“數(shù)據(jù)”自適應(yīng)中覆蓋的CupertinoThemeData的組件
CupertinoThemeData cupertinoOverrideTheme,
//SnackBarThemeData類(lèi)型可選命名參數(shù),用于自定義SnackBar的顏色、形狀、高度和行為的主題
SnackBarThemeData snackBarTheme,
//BottomSheetThemeData類(lèi)型可選命名參數(shù),用于自定義底部工作表的顏色、高度和形狀的主題
BottomSheetThemeData bottomSheetTheme,
//PopupMenuThemeData類(lèi)型可選命名參數(shù),用于自定義彈出菜單的顏色、形狀、高度和文本樣式的主題
PopupMenuThemeData popupMenuTheme,
//MaterialBannerThemeData類(lèi)型可選命名參數(shù),用于自定義材質(zhì)橫幅的顏色和文本樣式的主題
MaterialBannerThemeData bannerTheme,
//DividerThemeData類(lèi)型可選命名參數(shù),自定義分割線(xiàn)、垂直分割線(xiàn)等的顏色、厚度和縮進(jìn)的主題
DividerThemeData dividerTheme,
//ButtonBarThemeData類(lèi)型可選命名參數(shù),自定義按鈕欄小部件外觀(guān)和布局的主題
ButtonBarThemeData buttonBarTheme,
})
關(guān)于 ThemeData 的不同屬性只是翻譯自官方文檔,部分沒(méi)有做驗(yàn)證看效果,各位要自己試驗(yàn)看效果。
locale 用于設(shè)置應(yīng)用程序的本地語(yǔ)言初始化環(huán)境值。如果為 null ,則使用系統(tǒng)的區(qū)域設(shè)置值。如果 Localizations.locale 的值與 supportedLocales 之一匹配,則它將等于該語(yǔ)言環(huán)境。 否則它將是第一個(gè) supportedLocale。
關(guān)于國(guó)際化的使用方式查看官方網(wǎng)址:https://flutter.dev/docs/development/accessibility-and-localization/internationalization 。后續(xù)文章也會(huì)詳細(xì)介紹。
上述說(shuō)的都是單獨(dú)的界面,如果涉及到頁(yè)面的切換,比如查看列表的詳細(xì)信息,進(jìn)入下一級(jí)等,需要使用到 Navigator Widget 。
Navigator 是使用堆棧規(guī)則管理一組 Widget ,這些 Widget (界面)稱(chēng)為 Route 對(duì)象 。其繼承自 StatefulWidget ,是一個(gè)有狀態(tài)的 Widget 。其構(gòu)造方法如下:
const Navigator({
Key key,
//String類(lèi)型可選命名參數(shù),要顯示的第一個(gè)路由(頁(yè)面)的名稱(chēng)
this.initialRoute,
//RouteFactory類(lèi)型必傳參數(shù),調(diào)用以生成給定路由設(shè)置的路由
@required this.onGenerateRoute,
//RouteFactory類(lèi)型必傳參數(shù),當(dāng)onGenerateRoute無(wú)法生成路由時(shí)調(diào)用
this.onUnknownRoute,
//List<NavigatorObserver>類(lèi)型必傳參數(shù),導(dǎo)航器的觀(guān)察者列表
this.observers = const <NavigatorObserver>[],
})
在執(zhí)行路由線(xiàn)路切換需要使用 Navigator 的 push 和 pop 方法,如下:
//將制定路由添加到到導(dǎo)航的路由棧中
@optionalTypeArgs
static Future<T> push<T extends Object>(BuildContext context, Route<T> route) {
return Navigator.of(context).push(route);
}
//用于彈出最頂端的路由
@optionalTypeArgs
static bool pop<T extends Object>(BuildContext context, [ T result ]) {
return Navigator.of(context).pop<T>(result);
}
Navigator.push() 接收兩個(gè)參數(shù),一個(gè)是上下文信息,另一個(gè)是 Route ,可以使用 MaterialPageRote的實(shí)例。其構(gòu)造函數(shù)如下:
MaterialPageRoute({
//WidgetBuilder類(lèi)型必傳參數(shù),構(gòu)建路線(xiàn)的主要內(nèi)容
@required this.builder,
//RouteSettings類(lèi)型可選命名參數(shù),路由的設(shè)置
RouteSettings settings,
//bool類(lèi)型可選命名參數(shù),路由處于非活動(dòng)狀態(tài)時(shí)是否應(yīng)保留在內(nèi)存中
this.maintainState = true,
//bool類(lèi)型可選命名參數(shù),此頁(yè)面路由是否為全屏對(duì)話(huà)框。在iOS上,
//這些頁(yè)面從底部到頂部(而不是水平)進(jìn)行動(dòng)畫(huà)處理。
bool fullscreenDialog = false,
})
使用方式如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);;
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("HomePage"),
),
body: Builder(
builder: (BuildContext context){
return Container(
color: Colors.yellow,
child: Center(
child: RaisedButton(
child: Text("下一頁(yè)"),
onPressed: (){
Navigator.push(context, MaterialPageRoute(
builder: (context) => FirstPage(),
fullscreenDialog: false, //如果為true,則動(dòng)畫(huà)為從下至上推出
));
},
),
),
);
},
),
endDrawer: Drawer(),
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("FirstPage"),
),
body: Center(
child: RaisedButton(
child: Text("上一頁(yè)"),
onPressed: (){
Navigator.pop(context);
},
),
),
);
}
}
效果如下:

也可以通過(guò)設(shè)置 Material.routes 來(lái)設(shè)置導(dǎo)航的頂級(jí)路由路線(xiàn),通過(guò) Navigator.pushNamed 方法進(jìn)行導(dǎo)航界面切換,pushNamed 方法原型如下:
@optionalTypeArgs
static Future<T> pushNamed<T extends Object>(
//BuildContext類(lèi)型必傳參數(shù),上線(xiàn)文
BuildContext context,
//String類(lèi)型必傳參數(shù),路由路徑名稱(chēng)
String routeName, {
//Object類(lèi)型可選命名參數(shù),參數(shù)
Object arguments,
}) {
return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
}
使用方式如下:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
routes: {
"/first" : (context)=> FirstPage(),
},
);;
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("HomePage"),
),
body: Builder(
builder: (BuildContext context){
return Container(
color: Colors.yellow,
child: Center(
child: RaisedButton(
child: Text("下一頁(yè)"),
onPressed: (){
Navigator.pushNamed(context, "/first");
},
),
),
);
},
),
endDrawer: Drawer(),
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("FirstPage"),
),
body: Center(
child: RaisedButton(
child: Text("上一頁(yè)"),
onPressed: (){
Navigator.pop(context);
},
),
),
);
}
}
因?yàn)樵?home 中設(shè)置了首頁(yè),所以在 routes 中不需要設(shè)置 / 來(lái)表示首頁(yè),home 等同于 / 。
如果涉及到頁(yè)面?zhèn)髦?,正向傳值如果使?Navigator.push() ,可以使用被傳遞參數(shù)的 Widget 的構(gòu)造方法,使用Navigator.pushNamed() ,可以使用其第三個(gè)參數(shù) arguments 進(jìn)行參數(shù)設(shè)置。 反向可以使用 Navigator.pop 的參數(shù)進(jìn)行設(shè)置。如下:
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("HomePage"),
),
body: Builder(
builder: (BuildContext context){
return Container(
color: Colors.yellow,
child: Center(
child: RaisedButton(
child: Text("下一頁(yè)"),
onPressed: (){
//使用push
Navigator.push(context, MaterialPageRoute(
builder: (context) => FirstPage("hike"),
fullscreenDialog: false,
)
).then((value){
print(value);
});
},
),
),
);
},
),
endDrawer: Drawer(),
);
}
}
class FirstPage extends StatelessWidget {
FirstPage(this.userName);
final String userName;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("FirstPage"),
),
body: Center(
child: RaisedButton(
child: Text("上一頁(yè) 名字為:$userName"),
onPressed: (){
Navigator.pop(context, "返回給HomePage的值");
},
),
),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("HomePage"),
),
body: Builder(
builder: (BuildContext context){
return Container(
color: Colors.yellow,
child: Center(
child: RaisedButton(
child: Text("下一頁(yè)"),
onPressed: () async {
final result = await Navigator.pushNamed(context, "/first", arguments: <String, String>{
"name" : "hike",
"age" : "20",
});
print(result);
},
),
),
);
},
),
endDrawer: Drawer(),
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
RouteSettings setting = ModalRoute.of(context).settings;
final Map args = ModalRoute.of(context).settings.arguments;
print(setting.name);
return Scaffold(
appBar: AppBar(
title: Text("FirstPage"),
),
body: Center(
child: RaisedButton(
child: Text("上一頁(yè)"),
onPressed: (){
Navigator.pop(context, <String>["hike", "nick"]);
},
),
),
);
}
}
在正向傳值中,使用 Navigator.pushNamed() 方法時(shí),參數(shù) arguments 參數(shù)為 Object 類(lèi)型,所以可以定義任意類(lèi)型參數(shù),也可以使用 class 等包裝參數(shù)進(jìn)行傳遞。當(dāng)在接收參數(shù)頁(yè)面接收參數(shù)時(shí),使用 ModalRoute.of 進(jìn)行獲取,其返回一個(gè)帶有參數(shù)的當(dāng)前路由。
在反向傳值時(shí),當(dāng)調(diào)用 Navigator.pop() 時(shí),會(huì)將其中的參數(shù)包裝到該方法返回的 Feature 對(duì)象中。后續(xù)文章會(huì)詳細(xì)介紹??梢圆榭垂俜秸f(shuō)明文檔:https://flutter.dev/docs/cookbook/navigation/returning-data