先上效果图!
注: 红色块:整体背景,每一个颜色为一块内容,大家在`SliverToBoxAdapter`替换成自己的内容就好.
复制代码
1.使用NestedScrollView
进行滑动效果的制作.
使用 NestedScrollView
对body进行第一层的使用,代码如下:
@override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (context, innerBoxIsScrolled) {
return <Widget>[ SliverOverlapAbsorber( handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), child: _buildAppbarView(context, innerBoxIsScrolled), // 吸附的AppBar ) ];
},
body: _buildBodyView(), // AppBar下面的内容区域
),
);
}
复制代码
2.然后,实现AppBar,代码如下:
/// AppBar
Widget _buildAppbarView(context, bool innerBoxIsScrolled) {
return SliverAppBar(
pinned: true, // 吸附
centerTitle: true,
forceElevated: innerBoxIsScrolled,
expandedHeight: 140, // AppBar的高度
title: Text("这是标题"), // 标题,title参数接收的是一个Widget,可灵活使用.
backgroundColor: Colors.orangeAccent,
leading: Container(), // 占位,可删.
flexibleSpace: FlexibleSpaceBar( // 可伸缩属性,这里是重点
background: Container( // background接收的是这个Widget,可以使用Stack进行灵活的布局
height: 100,
child: Container(
height: 100,
color: Colors.red.shade200,
),
),
),
);
}
复制代码
3.再然后,实现body内容区域,代码如下:
Widget _buildBodyView() {
return SafeArea(
top: true,
child: Container(
margin: EdgeInsets.only(top: kToolbarHeight),
color: Colors.red,
child: CustomScrollView(
slivers: <Widget>[
SliverToBoxAdapter(
child: Container(
height: 150,
color: Colors.blue.shade200,
child: Center(child: Text('我是内容')
// child: _carousel(), // 这里就是我的内容,同下
),
)),
SliverToBoxAdapter(
child: Container(
height: 50,
color: Colors.green.shade200,
child: Center(child: Text('我是内容')
// child: _buildMessage(),
),
)),
SliverToBoxAdapter(
child: Container(
height: 50,
color: Colors.orange.shade200,
child: Center(child: Text('我是内容')
// child: _expandableWrap(),
),
)),
SliverToBoxAdapter(
child: Container(
height: 150,
color: Colors.pink.shade200,
child: Center(child: Text('我是内容')
// child: _buildVideoAndBookEntry(),
),
)),
SliverToBoxAdapter(
child: Container(
height: 150,
color: Colors.pink.shade200,
child: Center(child: Text('我是内容')
// child: _buildTopicTalkTwo(),
),
)),
],
),
),
);
}
复制代码
记另一种写法: 只不过有个问题是: 当内容不够一屏时,无法滑动到你想要的位置,但还算合理吧.
@override
Widget build(BuildContext context) {
return Scaffold(
body: _buildScaffoldBody()
);
}
Widget _buildScaffoldBody() {
return CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 120,
pinned: true,
title: Text('环境执法实务'),
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
background: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'lib/asset/images/home_share_gift_bg.png'),
fit: BoxFit.cover)),
child: SafeArea(
top: true,
child: Column(
children: <Widget>[
Container(
height: 50,
child: Text('',
style: TextStyle(
color: Colors.white, fontSize: 20))),
SearchInputWidget(
hasRightIcon: true,
text: '环境法规大全',
bgc: Colors.transparent,
icon1: Icons.bookmark,
icon2: Icons.add,
onTap: () => Navigator.pushNamed(context, '/search'),
),
],
),
),
)
],
),
),
// title: ,
),
SliverToBoxAdapter(
child: Column(
children: <Widget>[
_carousel(),
_buildMessage(),
_expandableWrap(),
_buildVideoAndBookEntry(),
_buildTopicTalkTwo(),
],
),
)
],
);
}
复制代码