Flutter Scaffold&AppBar
2019-12-12 本文已影响0人
DDLH
Scaffold是一个路由页的骨架,它包含了导航栏、抽屉菜单(Drawer)以及底部Tab导航菜单等
示例:
我们实现一个页面,它包含:
- 一个导航栏
- 导航栏右边有一个分享按钮
- 有一个抽屉菜单
- 有一个底部导航
- 右下角有一个悬浮的动作按钮
image.png
实现代码如下:
class ScaffoldRoute extends StatefulWidget {
@override
_ScaffoldRouteState createState() => _ScaffoldRouteState();
}
class _ScaffoldRouteState extends State<ScaffoldRoute> {
int _selectedIndex = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//导航栏
title: Text("App Name"),
actions: <Widget>[
//导航栏右侧分享菜单
IconButton(icon: Icon(Icons.share), onPressed: () {}),
],
),
drawer: _drawer, //抽屉
bottomNavigationBar: BottomNavigationBar(
// 底部导航
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(
icon: Icon(Icons.business), title: Text('Business')),
BottomNavigationBarItem(
icon: Icon(Icons.school), title: Text('School')),
],
currentIndex: _selectedIndex,
fixedColor: Colors.blue,
onTap: _onItemTapped,
),
floatingActionButton: FloatingActionButton(
//悬浮按钮
child: Icon(Icons.add),
onPressed: _onAdd),
);
}
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
void _onAdd() {}
// 抽屉Drawer案例
get _drawer => Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.lightBlueAccent,
),
margin: EdgeInsets.only(bottom: 8.0),
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 8.0),
child: Center(
child: SizedBox(
width: 60.0,
height: 60.0,
child: CircleAvatar(
child: Text('R'),
),
),
),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('设置'),
),
Divider(), //分割线
ListTile(
leading: Icon(Icons.close),
title: Text('关闭'),
onTap: () => Navigator.pop(context), // 关闭抽屉
)
],
),
);
}
上面代码中我们用到了如下组件:
组件名称 | 解释 |
---|---|
AppBar | 一个导航栏骨架 |
Drawer | 抽屉菜单 |
BottomNavigationBar | 底部导航栏 |
FloatingActionButton | 漂浮按钮 |
下面我们来学习一下这些组件。
AppBar
image.pngAppBar 有以下常用属性:
-
leading
- 导航栏最左侧的一个控件,在首页通常显示应用的 logo;在其他界面通常显示为返回按钮。 -
automaticallyImplyLeading
- 如果leading为null,是否自动实现默认的leading按钮,默认为true。 -
title
- 页面标题。 -
actions
→ List - 一个 Widget 列表,代表 Toolbar 中所显示的菜单,对于常用的菜单,通常使用 IconButton 来表示;对于不常用的菜单通常使用 PopupMenuButton 来显示为三个点,点击后弹出二级菜单。 -
bottom
- 导航栏底部菜单,通常是 TabBar。 -
elevation
→ double - 导航栏阴影,默认值4.0。 -
centerTitle
→ bool - 标题是否居中显示,默认值根据不同的操作系统,显示方式不一样。 -
backgroundColor
→ Color - Appbar 的颜色,默认值为 ThemeData.primaryColor。改值通常和下面的三个属性一起使用。 - brightness → Brightness - Appbar 的亮度,有白色和黑色两种主题,默认值为 ThemeData.primaryColorBrightness。
- iconTheme → IconThemeData - Appbar 上图标的颜色、透明度、和尺寸信息。默认值为 ThemeData.primaryIconTheme。
- textTheme → TextTheme - Appbar 上的文字样式。
自定义leading
如果给Scaffold添加了抽屉菜单,默认情况下Scaffold会自动将AppBar的leading设置为菜单按钮(如上面截图所示),点击它便可打开抽屉菜单。如果我们想自定义菜单图标,可以手动来设置leading,如:
Scaffold(
appBar: AppBar(
//导航栏
title: Text("App Name"),
leading: Builder(builder: (context) {
return IconButton(
icon: Icon(Icons.dashboard, color: Colors.white), //自定义图标
onPressed: () {
// 打开抽屉菜单
Scaffold.of(context).openDrawer();
},
);
}),
actions: <Widget>[
//导航栏右侧分享菜单
IconButton(icon: Icon(Icons.share), onPressed: () {}),
],
),
)
image.png
可以看到左侧菜单已经替换成功。
PopupMenuButton设置隐藏菜单
Scaffold(
appBar: AppBar(
//导航栏
...
actions: <Widget>[
//导航栏右侧分享菜单
IconButton(icon: Icon(Icons.share), onPressed: () {}),
// 隐藏的菜单
new PopupMenuButton<String>(
itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
this.SelectView(Icons.message, '发起群聊', 'A'),
this.SelectView(Icons.group_add, '添加服务', 'B'),
this.SelectView(Icons.cast_connected, '扫一扫码', 'C'),
],
onSelected: (String action) {
// 点击选项的时候
switch (action) {
case 'A':
break;
case 'B':
break;
case 'C':
break;
}
},
),
),
)
// 返回每个隐藏的菜单项
SelectView(IconData icon, String text, String id) {
return new PopupMenuItem<String>(
value: id,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Icon(icon, color: Colors.blue),
new Text(text),
],
));
}
image.png
image.png
什么是SliverAppBar
SliverAppBar 类似于Android中的CollapsingToolbarLayout,可以轻松实现页面头部展开、合并的效果。
与AppBar大部分的属性重合,相当于AppBar的加强版。
return Scaffold(
body: new CustomScrollView(
slivers: <Widget>[
new SliverAppBar(
// title: Text("标题"),
// flexibleSpace: new FlexibleSpaceBar( //滑动标题上移效果,去掉title
// title: new Text("标题标题标题"),
// centerTitle: true,
// collapseMode: CollapseMode.pin,
// ),
flexibleSpace: new FlexibleSpaceBar(
background: Image.asset('images/1.jpg', fit: BoxFit.fill),
title: new Text("标题标题标题"),
),
),
new SliverFixedExtentList(
itemExtent: 50.0,
delegate: new SliverChildBuilderDelegate(
(context, index) => new ListTile(
title: new Text("Item $index"),
),
childCount: 30,
),
),
],
),
);
image.png
image.png