Scaffold用于實(shí)現(xiàn)基本的Material Design可視化結(jié)構(gòu),其提供了顯示 drawers(抽屜),snack bars(提示信息)和bottom sheets(疊加層)的API。要顯示snackbar或一個持久的bottom sheet,需要使用Scaffold靜態(tài)的of方法來獲取當(dāng)前BuildContext的ScaffoldState(Scaffold的狀態(tài)),并使用ScaffoldState.showSnackBar(用于在Scaffold底部顯示SnackBar)和ScaffoldStates.showBottomSheet(用于在Scaffold中顯示BottomSheet)函數(shù)。
我們先來看看官方給出的案例:
import 'package:flutter/material.dart';
//此示例顯示了一個帶有AppBar(標(biāo)題欄),BottomAppBar(底部標(biāo)題欄)和FloatingActionButton(懸浮按鈕)的Scaffold。
//使用Center組件將文本組件放置在Scaffold 內(nèi)容區(qū)正中,
//并且使用FloatingActionButtonLocation.centerDocked函數(shù)將FloatingActionButton位于BottomAppBar的正中。
//FloatingActionButton的點(diǎn)擊事件調(diào)用一個遞增的計(jì)數(shù)器,然后改變Scaffold內(nèi)容區(qū)的數(shù)值。
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter Code Sample for material.Scaffold",
theme: ThemeData(
primarySwatch: Colors.blue
),
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget{
MyStatefulWidget({Key key}): super(key:key);
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget>{
int _count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(//初始化Scaffold組件
appBar: AppBar(//標(biāo)題欄
title: Text('Sample Code'),//使用Text組件顯示標(biāo)題欄文字
),
body: Center(//使用Center組件將內(nèi)容區(qū)文本居中
child: Text('You have pressed the button $_count times.'),
),
bottomNavigationBar: BottomAppBar(//底部標(biāo)題欄
child: Container(//內(nèi)容區(qū)以Container組件填充,并設(shè)置高度
height: 50.0,
),
),
floatingActionButton: FloatingActionButton(//浮動按鈕
onPressed: () => setState(() {//浮動按鈕點(diǎn)擊事件
_count++;
}),
//長按按鈕顯示的文字信息
tooltip: 'Increment Counter',
child: Icon(Icons.add),//浮動按鈕內(nèi)容區(qū)圖標(biāo)
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,//設(shè)置浮動按鈕位置
);
}
}
效果如下所示:

Scaffold應(yīng)用
Scaffold將填充整個窗口或設(shè)備屏幕的可用空間。當(dāng)設(shè)備鍵盤出現(xiàn)時,Scaffold會根據(jù)MediaQuery組件的MediaQueryData.viewInsets重繪Scaffold。默認(rèn)情況下,Scaffold組件會調(diào)整大小以便為鍵盤騰出空間。我們也可以通過resizeToAvoidBottomInset設(shè)置為false來禁止調(diào)整大小,這樣的話,Scaffold將不會再進(jìn)行重繪。
//鍵盤出現(xiàn)時,是否重繪Scaffold
class ScaffoldKeyboard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "打開鍵盤重繪Scaffold",
theme: ThemeData(
primarySwatch: Colors.lightBlue
),
home: Scaffold(
body: Center(
child: TextField(
keyboardType: TextInputType.numberWithOptions(),
),
),
resizeToAvoidBottomInset: true,//是否禁止Scaffold調(diào)整大小,true開啟重繪,false禁止重繪
),
);
}
}
效果如下所示:

支持自動調(diào)整大小

不支持自動調(diào)整大小
Scaffold是MaterialApp組件的單頂級容器,因此其再不需要嵌套Scaffold。如果我們使用選項(xiàng)卡UI時,bottomNavigationBar時TabBar,而body中是TabBarView,我們需要為每個選項(xiàng)卡設(shè)置不同的標(biāo)題文字,這時我們最好使用監(jiān)聽器添加選項(xiàng)卡到TabController中,以便每次選擇后能夠重置應(yīng)用程序的AppBar標(biāo)題。
void main() => runApp(MyTabbedPage());
//選項(xiàng)卡
class MyTabbedPage extends StatefulWidget {
const MyTabbedPage({Key key}) : super(key: key);
@override
_MyTabbedPageState createState() => _MyTabbedPageState();
}
class _MyTabbedPageState extends State<MyTabbedPage> with SingleTickerProviderStateMixin {
final List<Tab> myTabs = <Tab> [
Tab(text: '首頁', icon: Icon(Icons.home),),
Tab(text: '消息', icon: Icon(Icons.message),),
Tab(text: '我的', icon: Icon(Icons.account_circle),)
];
TabController _tabController;
String appBarTitle = "首頁";
@override
void initState() {
super.initState();
//監(jiān)聽選項(xiàng)卡事件,選擇選項(xiàng)卡重置AppBar標(biāo)題
_tabController = TabController(length: myTabs.length, vsync: this)..addListener(() {
if(_tabController.indexIsChanging) {
setState(() {
appBarTitle = '${myTabs[_tabController.index].text}';
});
}
});
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.lightBlue,
),
home: Scaffold(
appBar: AppBar(
title: Text(appBarTitle),
),
bottomSheet: TabBar(
tabs: myTabs,
controller: _tabController,
),
body: TabBarView(
controller: _tabController,
children: myTabs.map((Tab tab) {
return Center(child: Text(tab.text),);
}).toList(),
),
),
);
}
}
效果圖如下:

首頁

消息
Scaffold屬性

Scaffold屬性
本節(jié)內(nèi)容到此結(jié)束,若在使用過程中遇到問題,歡迎留言交流,我們一起成長。