如今在 App 中,常见的一个效果就是折叠工具栏,在 Android 上,这种效果能够经过 CollapsingToolbarLayout + NestedScrollView + AppBarLayout 来实现,在 Flutter 里面,也有 NestedScrollView 和 SliverAppBar 来实现这样的效果。git
先看最简单的状况,只使用 AppBargithub
通常状况下,咱们的 App 都是这样的:编程
return Scaffold(
appBar: AppBar(
title: Text("标题"),
),
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListTile(title:Text( "标题$index"),);
},
itemCount: 50,
),
);
复制代码
效果是这样的:bash
SliverAppBar 实际上是属于 Slivers 里面的一个控件,而 Slivers 包含的可滚动的控件通常都是在复杂的滑动嵌套的场景下使用,通常都是做为 CustomScrollView 的子 Widget 来使用。好比 ListView 对应的 Slivers 组件是 SliverFixedExtentList,GirdView 对应的是 SliverGrid。CustomScrollView 的做用就是使这些 Sliver 组件的滑动效果同一的。微信
若是是使用 NestedScrollView + SliverAppbar 是这样的:app
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
title: Text("标题"),
floating: false,
snap: false,
pinned: true,
)
];
},
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListTile(title:Text( "标题$index"),);
},
itemCount: 50,
),
),
);
复制代码
效果:工具
效果其实和上面的同样。flex
接着把 pined 属性值改成 false 。效果以下:ui
其余属性以下:this
const SliverAppBar({
Key key,
this.leading, //在标题左侧显示的一个控件,一般为一个图标
this.automaticallyImplyLeading = true,//? 控制是否应该尝试暗示前导小部件为null
this.title, //标题
this.actions, //右侧的操做菜单,最多三个
this.flexibleSpace, //能够展开的区域,一般是一个FlexibleSpaceBar
this.bottom, //底部内容区域,一般是 TabBar
this.elevation, //阴影
this.forceElevated = false,
this.backgroundColor, //APP bar 的颜色,默认值为 ThemeData.primaryColor
this.brightness, //Appbar的主题,有白色和黑色两种主题
this.iconTheme, //Appbar 上图标的颜色、透明度、和尺寸信息
this.textTheme, //Appbar 上的文字主题
this.primary = true, //此应用栏是否显示在屏幕顶部
this.centerTitle, //标题是否居中显示,默认值根据不一样的操做系统
this.titleSpacing = NavigationToolbar.kMiddleSpacing,//横轴上标题内容 周围的间距
this.expandedHeight, //展开高度
this.floating = false, //是否随着滑动隐藏标题
this.pinned = false, //是否固定在顶部
this.snap = false, //与floating结合使用
})
复制代码
指定 flexibleSpace 就能够定义展开区域。
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
/* SliverAppBar(
title: Text("标题"),
floating: false,
snap: false,
pinned: true,
)
*/
SliverAppBar(
expandedHeight: 200.0,
floating: true,
snap: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: Text("标题",
style: TextStyle(
color: Colors.redAccent,
fontSize: 16.0,
)),
background: Image.asset(
"images/bg.jpg",
fit: BoxFit.fill,
)
),
)
];
},
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListTile(title:Text( "标题$index"),);
},
itemCount: 50,
),
),
);
复制代码
效果:
SliverBar 中指定 bottom 属性为 TabBar,同时 NestedScrollView body 属性指定为 TabVarView
return Scaffold(
body: NestedScrollView(
controller: _scrollviewController,
headerSliverBuilder: (context, boxIsScrolled) {
return [
SliverAppBar(
pinned: true,
floating: true,
elevation: 0.5,
forceElevated: true,
//backgroundColor: Colors.grey,
expandedHeight: 240,
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.pin, //视差效果
background: Container(
//color: Colors.grey,
child: Column(
children: <Widget>[
Container(
height: 210.0,
width: 420,
color: Colors.blue,
child: Image.asset(
"images/bg.jpg",
fit: BoxFit.fitWidth,
),
)
],
),
),
),
bottom: TabBar(controller: _tabController, tabs: [
Tab(
text: "首页",
),
Tab(
text: "消息",
),
Tab(
text: "购物",
),
Tab(
text: "个人",
)
]),
),
];
},
body: TabBarView(
controller: _tabController,
children: [
Center(
child: Text("one"),
),
Center(
child: Text("two"),
),
Center(
child: Text("three"),
),
Center(
child: Text("four"),
),
]
)
),
);
复制代码
效果:
欢迎关注「Flutter 编程开发」微信公众号 。