APPBar:应用栏,它通常应用于Scaffold.appBar属性,该属性将应用栏放置在屏幕顶部的固定高度小部件中,对于可滚动的应用栏可查看SliverAppBar,它将Appbar嵌入到sliver中以便在CustomScrollView中使用。应用栏由工具栏组成,或者是工具栏和其他widget组合形式,例如tabBar和FlexibleSpaceBar。先看看它的属性
AppBar({
Key key,
this.leading,
this.automaticallyImplyLeading = true,
this.title,
this.actions,
this.flexibleSpace,
this.bottom,
this.elevation = 4.0,
this.backgroundColor,
this.brightness,
this.iconTheme,
this.textTheme,
this.primary = true,
this.centerTitle,
this.titleSpacing = NavigationToolbar.kMiddleSpacing,
this.toolbarOpacity = 1.0,
this.bottomOpacity = 1.0,
})
leading:显示在[title]前面的小部件。如果该值为null,并且[automaticallyImplyLeading]设置为true,则[AppBar]将暗示一个适当的小部件。 例如,如果[AppBar]位于也具有[Drawer]的[Scaffold]中,则[Scaffold]将用打开抽屉的[IconButton]填充此小部件(使用[Icons.menu])。 如果没有[抽屉]并且父级[导航器]可以返回,则[AppBar]将使用调用[Navigator.maybePop]的[BackButton]。 以下代码显示了如何手动指定抽屉按钮而不是依靠[automaticallyImplyLeading]:
AppBar(
/// leading: Builder(
/// builder: (BuildContext context) {
/// return IconButton(
/// icon: const Icon(Icons.menu),
/// onPressed: () { Scaffold.of(context).openDrawer(); },
/// tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
/// );
/// },
/// ),
/// )
title:一般是一个Text widget,显示标题
actions:显示在title后的widget,一般为IconButtons,一般把不常用的放到popupMenuButton中,并把它作为最后一个action。
flexibleSpace: 通常为[FlexibleSpaceBar],该小部件堆叠在工具栏和选项卡的后面。 它的高度将与应用栏的整体高度相同。除非[AppBar]的容器更改了[AppBar]的大小,否则灵活的空间实际上并不灵活。 [CustomScrollView]中的[SliverAppBar]滚动时会更改[AppBar]的高度。 有关详细信息,请参见[FlexibleSpaceBar]。通常用在SliverAPPBar中。
bottom:显示在应用栏的底部。通常为TabBar,除此之外这个属性的内容只能是实现了PreferredSizeWidget的widget才可以。
primary:此应用栏是否显示在屏幕顶部。如果为true,则应用栏的工具栏元素和[底部]小部件将在顶部填充系统状态栏的高度。 [flexibleSpace]的布局不受[primary]属性的影响。示例代码如下
class AppBarDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _AppBarDemoState();
}
}
class _AppBarDemoState extends State<AppBarDemo> with SingleTickerProviderStateMixin{
TabController _tabController;
ScrollController _scrollViewController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 6, vsync: this);
_scrollViewController = ScrollController();
}
@override
void dispose() {
_tabController.dispose();
_scrollViewController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AppBarDemo"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.home),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.access_alarm),
onPressed: () {},
),
PopupMenuButton(
initialValue: "first",
child: Icon(Icons.more_horiz),
itemBuilder: (BuildContext context)=> <PopupMenuEntry>[
PopupMenuItem(
value: "first", child: Text("This is the firstItem")),
PopupMenuItem(
value: "second", child: Text("This is the secondItem"))]
,
)
],
// flexibleSpace: FlexibleSpaceBar(
// centerTitle: true,
// title: Text("flexibleSpace",
// style: TextStyle(
// color: Colors.white,
// fontSize: 16.0,
// )),
// background: Image.network(
// "https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&h=350",
// fit: BoxFit.cover,
//
// /// 色彩叠加 UI可以理解为两个色彩涂层,在图片混合一个色层
// // color: Colors.redAccent, //混合的颜色
// // colorBlendMode: BlendMode.darken, //混合方式
//
// ///图片重复填充容器
// // repeat: ImageRepeat.repeat,
// )),
bottom: TabBar(
isScrollable: true,
controller: _tabController,
tabs: <Widget>[
Tab(text: "Tabs 1"),
Tab(text: "Tabs 2"),
Tab(text: "Tabs 3"),
Tab(text: "Tabs 4"),
Tab(text: "Tabs 5"),
Tab(text: "Tabs 6"),
],),
primary: true,
),
);
}
}
效果为


SliverAppBar:它与AppBar都是继承自StatefulWidget,都代表Toolbar,它的构造方法与Appbar基本相同,但他却不能直接使用,他通常与ScrollView一起使用。他们二者的区别在于AppBar位置固定,SliverAppBar是可以跟随内容滚动的。下面我们将其放入NestScrollView中
class SliverAppBarDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _SliverAppBarDemoState();
}
}
class _SliverAppBarDemoState extends State<SliverAppBarDemo> {
final List<ListItem> listData = [];
@override
void initState() {
super.initState();
for (int i = 0; i < 20; i++) {
listData.add(ListItem("我是测试标题$i", Icons.cake));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body:NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
leading:IconButton(icon: Icon(Icons.arrow_back), onPressed: (){}),// 在标题前面显示的一个控件,在首页通常显示应用的 logo;在其他界面通常显示为返回按钮
//title, // Toolbar 中主要内容,通常显示为当前界面的标题文字
//actions, // 一个 Widget 列表,代表 Toolbar 中所显示的菜单,对于常用的菜单,通常使用 IconButton 来表示;对于不常用的菜单通常使用 PopupMenuButton 来显示为三个点,点击后弹出二级菜单
//flexibleSpace,
//bottom, //底部内容区域
//elevation, //阴影,纸墨设计中控件的 z 坐标顺序,默认值为 4,对于可滚动的 SliverAppBar,当 SliverAppBar 和内容同级的时候,该值为 0, 当内容滚动 SliverAppBar 变为 Toolbar 的时候,修改 elevation 的值
//flexibleSpace:一个显示在 AppBar 下方的控件,高度和 AppBar 高度一样,可以实现一些特殊的效果,该属性通常在 SliverAppBar 中使用
//backgroundColor, // 背景色,APP bar 的颜色,默认值为 ThemeData.primaryColor。改值通常和下面的三个属性一起使用
//brightness, // 主题明亮,App bar 的亮度,有白色和黑色两种主题,默认值为 ThemeData.primaryColorBrightness
//iconTheme, // 图标主题,App bar 上图标的颜色、透明度、和尺寸信息。默认值为 ThemeData.primaryIconTheme
//textTheme, //文字主题, App bar 上的文字样式。默认值为 ThemeData.primaryTextTheme
//centerTitle, //标题是否居中, 标题是否居中显示,默认值根据不同的操作系统,显示方式不一样
primary: true,
//是否预留高度
forceElevated: false,
automaticallyImplyLeading: true,
titleSpacing: NavigationToolbar.kMiddleSpacing,
snap: false,
//与floating结合使用
expandedHeight: 200.0,
//展开高度
floating: false,
//是否随着滑动隐藏标题
pinned: true,
//是否固定在顶部
flexibleSpace: FlexibleSpaceBar(
//可以展开区域,通常是一个FlexibleSpaceBar
centerTitle: true,
title: Text("我是一个帅气的标题",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
)),
background: Image.network(
//"http://h.hiphotos.baidu.com/image/pic/item/342ac65c103853434cc02dda9f13b07eca80883a.jpg",
"http://b.zol-img.com.cn/desk/bizhi/image/6/960x600/1432800027589.jpg",
//"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1531798262708&di=53d278a8427f482c5b836fa0e057f4ea&imgtype=0&src=http%3A%2F%2Fh.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F342ac65c103853434cc02dda9f13b07eca80883a.jpg",
fit: BoxFit.fill,
)),
)
];
},
body: Center(
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return ListItemWidget(listData[index]);
},
itemCount: listData.length,
),
),
) ,
);
}
}
class ListItem {
final String title;
final IconData iconData;
ListItem(this.title, this.iconData);
}
class ListItemWidget extends StatelessWidget {
final ListItem listItem;
ListItemWidget(this.listItem);
@override
Widget build(BuildContext context) {
return InkWell(
child: ListTile(
leading: Icon(listItem.iconData),
title: Text(listItem.title),
),
onTap: () {},
);
}
}
效果为
