在开始说明Scaffold组件之前,先大致讲述一下Material Design风格。Material Design也成为纸墨设计风格,是由Google退出的全新的设计语言,这种设计语言旨在为手机、平板电脑、台式机和其他平台提供更一致、更广泛的外观和感觉,它是一种非常有质感的设计风格,并会提供一些默认的交互动画。
Scaffold实现了基本的Material Design布局。只要是在Material Design中定义过的单个界面实现的布局元素,都可以使用Scaffold来绘制。
Scaffold常用的属性如下:
属性名 | 类型 | 说明 |
---|---|---|
appBar | AppBar | 显示在界面顶部的一个AppBar |
body | Widget | 当前界面所显示的主要内容 |
floatingActionButton | Widget | 在Material Design 中定义的一个功能 |
persistentFooterButtons | List | 固定在下方显示的按钮 |
drawer | Widget | 侧边栏组件 |
bottomNavigationBar | Widget | 显示在底部的导航栏按钮 |
backgroundColor | Color | 当前界面所显示的主要内容 |
body | Widget | 背景色 |
resizeToAvoidBottomPadding | bool | 控制界面内容body是否重新布局来避免底部被覆盖,比如当键盘显示时,重新布局避免被键盘盖住内容。默认值为true |
class Scaffold extends StatefulWidget {
const Scaffold({
Key key,
this.appBar,
this.body,
this.floatingActionButton,
this.floatingActionButtonLocation,
this.floatingActionButtonAnimator,
this.persistentFooterButtons,
this.drawer,
this.endDrawer,
this.bottomNavigationBar,
this.bottomSheet,
this.backgroundColor,
this.resizeToAvoidBottomPadding,
this.resizeToAvoidBottomInset,
this.primary = true,
this.drawerDragStartBehavior = DragStartBehavior.start,
this.extendBody = false,
this.drawerScrimColor,
}) : assert(primary != null),
assert(extendBody != null),
assert(drawerDragStartBehavior != null),
super(key: key);
final bool extendBody;
final PreferredSizeWidget appBar;
final Widget body;
final Widget floatingActionButton;
final FloatingActionButtonLocation floatingActionButtonLocation;
final FloatingActionButtonAnimator floatingActionButtonAnimator;
final List persistentFooterButtons;
final Widget drawer;
final Widget endDrawer;
final Color drawerScrimColor;
final Color backgroundColor;
final Widget bottomNavigationBar;
final Widget bottomSheet;
@Deprecated('Use resizeToAvoidBottomInset to specify if the body should resize when the keyboard appears')
final bool resizeToAvoidBottomPadding;
final bool resizeToAvoidBottomInset;
final bool primary;
final DragStartBehavior drawerDragStartBehavior;
static ScaffoldState of(BuildContext context, { bool nullOk = false }) {
assert(nullOk != null);
assert(context != null);
final ScaffoldState result = context.ancestorStateOfType(const TypeMatcher());
if (nullOk || result != null)
return result;
throw FlutterError(
'Scaffold.of() called with a context that does not contain a Scaffold.\n'
'No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). '
'This usually happens when the context provided is from the same StatefulWidget as that '
'whose build function actually creates the Scaffold widget being sought.\n'
'There are several ways to avoid this problem. The simplest is to use a Builder to get a '
'context that is "under" the Scaffold. For an example of this, please see the '
'documentation for Scaffold.of():\n'
' https://docs.flutter.io/flutter/material/Scaffold/of.html\n'
'A more efficient solution is to split your build function into several widgets. This '
'introduces a new context from which you can obtain the Scaffold. In this solution, '
'you would have an outer widget that creates the Scaffold populated by instances of '
'your new inner widgets, and then in these inner widgets you would use Scaffold.of().\n'
'A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, '
'then use the key.currentState property to obtain the ScaffoldState rather than '
'using the Scaffold.of() function.\n'
'The context used was:\n'
' $context'
);
}
static ValueListenable geometryOf(BuildContext context) {
final _ScaffoldScope scaffoldScope = context.inheritFromWidgetOfExactType(_ScaffoldScope);
if (scaffoldScope == null)
throw FlutterError(
'Scaffold.geometryOf() called with a context that does not contain a Scaffold.\n'
'This usually happens when the context provided is from the same StatefulWidget as that '
'whose build function actually creates the Scaffold widget being sought.\n'
'There are several ways to avoid this problem. The simplest is to use a Builder to get a '
'context that is "under" the Scaffold. For an example of this, please see the '
'documentation for Scaffold.of():\n'
' https://docs.flutter.io/flutter/material/Scaffold/of.html\n'
'A more efficient solution is to split your build function into several widgets. This '
'introduces a new context from which you can obtain the Scaffold. In this solution, '
'you would have an outer widget that creates the Scaffold populated by instances of '
'your new inner widgets, and then in these inner widgets you would use Scaffold.geometryOf().\n'
'The context used was:\n'
' $context'
);
return scaffoldScope.geometryNotifier;
}
static bool hasDrawer(BuildContext context, { bool registerForUpdates = true }) {
assert(registerForUpdates != null);
assert(context != null);
if (registerForUpdates) {
final _ScaffoldScope scaffold = context.inheritFromWidgetOfExactType(_ScaffoldScope);
return scaffold?.hasDrawer ?? false;
} else {
final ScaffoldState scaffold = context.ancestorStateOfType(const TypeMatcher());
return scaffold?.hasDrawer ?? false;
}
}
@override
ScaffoldState createState() => ScaffoldState();
}
class TextDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('文本组件'),
),
backgroundColor: Colors.grey,
bottomNavigationBar: BottomAppBar(
child: Container(
height: 50.0,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: '增加',
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
body: new Column(
children: [
new Text(
'红色+黑色删除线+25号',
style: new TextStyle(
color: const Color(0xffff0000),
decoration: TextDecoration.lineThrough,
decorationColor: const Color(0xff000000),
fontSize: 25.0),
),
new Text(
'橙色+下划线+24号',
style: new TextStyle(
color: const Color(0xffff9900),
decoration: TextDecoration.underline,
fontSize: 24.0,
),
),
new Text(
'虚线上划线+23号+倾斜',
style: new TextStyle(
decoration: TextDecoration.overline,
decorationStyle: TextDecorationStyle.dashed,
fontSize: 23.0,
fontStyle: FontStyle.italic,
),
),
new Text(
'24号+加粗',
style: new TextStyle(
fontSize: 23.0,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
letterSpacing: 6.0,
),
)
],
),
);
}
}