转载请声明出处!!!
先来简单看下部分效果图:
本文内容可能有点多,但是都很简单,配上效果图味道更佳~
什么是SliverAppBar
SliverAppBar 类似于Android中的CollapsingToolbarLayout
,可以轻松实现页面头部展开、合并的效果。
与AppBar大部分的属性重合,相当于AppBar的加强版。
先从最基本的效果开始,一步一步做到全效果。
常用属性
const SliverAppBar({
Key key,
,//左侧的图标或文字,多为返回箭头
= true,//没有leading为true的时候,默认返回箭头,没有leading且为false,则显示title
,//标题
,//标题右侧的操作
,//可以理解为SliverAppBar的背景内容区
,//SliverAppBar的底部区
,//阴影
= false,//是否显示阴影
,//背景颜色
,//状态栏主题,默认,可选参数light
,//SliverAppBar图标主题
,//action图标主题
,//文字主题
= true,//是否显示在状态栏的下面,false就会占领状态栏的高度
,//标题是否居中显示
= ,//标题横向间距
,//合并的高度,默认是状态栏的高度加AppBar的高度
= false,//滑动时是否悬浮
= false,//标题栏是否固定
= false,//配合floating使用
})
基本效果
return Scaffold(
body: new CustomScrollView(
slivers: <Widget>[
new SliverAppBar(
title: Text("标题"),
expandedHeight: 230.0,
floating: false,
pinned: true,
snap: false,
),
new SliverFixedExtentList(
itemExtent: 50.0,
delegate: new SliverChildBuilderDelegate(
(context, index) => new ListTile(
title: new Text("Item $index"),
),
childCount: 30,
),
),
],
),
);
这是最最最基本的效果了,但是也简陋的不行,下面开始一步一步改造。
添加leading
leading: new IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {},
),
添加actions
actions: <Widget>[
new IconButton(
icon: Icon(),
onPressed: () {
print("添加");
},
),
new IconButton(
icon: Icon(Icons.more_horiz),
onPressed: () {
print("更多");
},
),
],
滑动标题上移效果
去掉title,添加flexibleSpace
flexibleSpace: new FlexibleSpaceBar(
title: new Text("标题标题标题"),
centerTitle: true,
collapseMode: ,
),
背景图片沉浸式
项目根目录下新建images文件夹,存放图片,随便选一张即可。
要加载本地图片,还需要在 文件中配置一下
assets:
- images/
修改flexibleSpace
flexibleSpace: new FlexibleSpaceBar(
background: ("images/", fit: ),
),
各种滑动效果演示
-
floating: false, pinned: true, snap: false:
-
floating: true, pinned: true, snap: true:
-
floating: false, pinned: false, snap: false:
-
floating: true, pinned: false, snap: false:
总结:仔细观察,区别主要在于:
- 标题栏是否跟着一起滑动
- 上滑的时候,SliverAppBar是直接滑上去还是先合并然后再滑上去。
- 下拉的时候,SliverAppBar是直接拉下来还是先拉下来再展开。
添加TabBar
在SliverAppBar的bottom属性中添加TabBar,直接改造源码中的例子
var _tabs = <String>[];
_tabs = <String>[
"Tab 1",
"Tab 2",
"Tab 3",
];
/// 加TabBar
DefaultTabController(
length: _tabs.length, // This is the number of tabs.
child: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
// These are the slivers that show up in the "outer" scroll view.
return <Widget>[
SliverOverlapAbsorber(
handle:
(context),
child: SliverAppBar(
leading: new IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {},
),
title: const Text('标题'),
centerTitle: false,
pinned: true,
floating: false,
snap: false,
primary: true,
expandedHeight: 230.0,
elevation: 10,
//是否显示阴影,直接取值innerBoxIsScrolled,展开不显示阴影,合并后会显示
forceElevated: innerBoxIsScrolled,
actions: <Widget>[
new IconButton(
icon: Icon(Icons.more_horiz),
onPressed: () {
print("更多");
},
),
],
flexibleSpace: new FlexibleSpaceBar(
background: ("images/", fit: ),
),
bottom: TabBar(
tabs: _tabs.map((String name) => Tab(text: name)).toList(),
),
),
),
];
},
body: TabBarView(
// These are the contents of the tab views, below the tabs.
children: _tabs.map((String name) {
//SafeArea 适配刘海屏的一个widget
return SafeArea(
top: false,
bottom: false,
child: Builder(
builder: (BuildContext context) {
return CustomScrollView(
key: PageStorageKey<String>(name),
slivers: <Widget>[
SliverOverlapInjector(
handle:
(
context),
),
SliverPadding(
padding: const (10.0),
sliver: SliverFixedExtentList(
itemExtent: 50.0, //item高度或宽度,取决于滑动方向
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return ListTile(
title: Text('Item $index'),
);
},
childCount: 30,
),
),
),
],
);
},
),
);
}).toList(),
),
),
),
关于TabBar的使用可以看这篇:/yechaoa/article/details/90482127
ok,以上的效果基本满足日常开发需求了,也可以自己改改属性测试效果。
demo github : /yechaoa/flutter_sliverappbar