第二章●第一节:脚手架(Scaffold)
2019-04-29 本文已影响7人
白晓明
Scaffold用于实现基本的Material Design可视化结构,其提供了显示 drawers(抽屉),snack bars(提示信息)和bottom sheets(叠加层)的API。要显示snackbar或一个持久的bottom sheet,需要使用Scaffold静态的of方法来获取当前BuildContext的ScaffoldState(Scaffold的状态),并使用ScaffoldState.showSnackBar(用于在Scaffold底部显示SnackBar)和ScaffoldStates.showBottomSheet(用于在Scaffold中显示BottomSheet)函数。
我们先来看看官方给出的案例:
import 'package:flutter/material.dart';
//此示例显示了一个带有AppBar(标题栏),BottomAppBar(底部标题栏)和FloatingActionButton(悬浮按钮)的Scaffold。
//使用Center组件将文本组件放置在Scaffold 内容区正中,
//并且使用FloatingActionButtonLocation.centerDocked函数将FloatingActionButton位于BottomAppBar的正中。
//FloatingActionButton的点击事件调用一个递增的计数器,然后改变Scaffold内容区的数值。
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(//标题栏
title: Text('Sample Code'),//使用Text组件显示标题栏文字
),
body: Center(//使用Center组件将内容区文本居中
child: Text('You have pressed the button $_count times.'),
),
bottomNavigationBar: BottomAppBar(//底部标题栏
child: Container(//内容区以Container组件填充,并设置高度
height: 50.0,
),
),
floatingActionButton: FloatingActionButton(//浮动按钮
onPressed: () => setState(() {//浮动按钮点击事件
_count++;
}),
//长按按钮显示的文字信息
tooltip: 'Increment Counter',
child: Icon(Icons.add),//浮动按钮内容区图标
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,//设置浮动按钮位置
);
}
}
Scaffold应用效果如下所示:
Scaffold将填充整个窗口或设备屏幕的可用空间。当设备键盘出现时,Scaffold会根据MediaQuery组件的MediaQueryData.viewInsets重绘Scaffold。默认情况下,Scaffold组件会调整大小以便为键盘腾出空间。我们也可以通过resizeToAvoidBottomInset设置为false来禁止调整大小,这样的话,Scaffold将不会再进行重绘。
//键盘出现时,是否重绘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调整大小,true开启重绘,false禁止重绘
),
);
}
}
支持自动调整大小效果如下所示:
不支持自动调整大小
Scaffold是MaterialApp组件的单顶级容器,因此其再不需要嵌套Scaffold。如果我们使用选项卡UI时,bottomNavigationBar时TabBar,而body中是TabBarView,我们需要为每个选项卡设置不同的标题文字,这时我们最好使用监听器添加选项卡到TabController中,以便每次选择后能够重置应用程序的AppBar标题。
void main() => runApp(MyTabbedPage());
//选项卡
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();
//监听选项卡事件,选择选项卡重置AppBar标题
_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属性
本节内容到此结束,若在使用过程中遇到问题,欢迎留言交流,我们一起成长。