Flutter教学目录持续更新中
Github源代码持续更新中
1.NestedScrollView介绍
一个可以嵌套其它可滚动widget的widget
2.NestedScrollView属性
- controller:ScrollController
- scrollDirection = Axis.vertical:滑动方向
- reverse = false:是否倒序
- physics:控制用户滚动视图的交互
- headerSliverBuilder:NestedScrollViewHeaderSliversBuilder
- body:Widget
3.使用
_mySliverAppBar() {
return SliverAppBar(
title: Text('NestedScrollView'),
expandedHeight: 200,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
ImageUrlConstant.imageUrl1,
fit: BoxFit.cover,
),
collapseMode: CollapseMode.parallax,
),
);
}
@override
Widget build(BuildContext context) {
return NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
_mySliverAppBar(),
];
},
body: Container(
color: Colors.blue,
),
);
}
NestedScrollView的头部需要sliver组件,但是body可以使用非sliver组件,这样它就可以支持在实现tab,page联动的效果,这是CustomScrollView无法提供的。
4.NestedScrollView的一些注意事项
NestedScrollView+ListView+SliverAppBar
_mySliverAppBar() {
return SliverAppBar(
title: Text('NestedScrollView'),
expandedHeight: 200,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
ImageUrlConstant.imageUrl1,
fit: BoxFit.cover,
),
collapseMode: CollapseMode.parallax,
),
);
}
_myItem(int index) {
return Container(
color: Colors.yellow,
child: ListTile(
title: Text('List $index'),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
_mySliverAppBar(),
];
},
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return _myItem(index);
},
itemCount: 15,
),
),
);
}
这种情况下ListView是无法得到准确的头部展开折叠高度的,那么flutter提供了解决方案:SliverOverlapAbsorber+SliverOverlapInjector
_mySliverAppBar() {
return SliverAppBar(
title: Text('NestedScrollView'),
expandedHeight: 200,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
ImageUrlConstant.imageUrl1,
fit: BoxFit.cover,
),
collapseMode: CollapseMode.parallax,
),
);
}
_myItem(int index) {
return Container(
color: Colors.yellow,
child: ListTile(
title: Text('List $index'),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
sliver: _mySliverAppBar(),
)
];
},
body: Builder(
builder: (context) {
return CustomScrollView(
slivers: [
SliverOverlapInjector(
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return _myItem(index);
},
childCount: 15,
),
),
],
);
},
),
),
);
}
这里有个需要注意的地方,那就是NestedScrollView的body必须构建一个Builder,使用NestedScrollView的context去创建SliverOverlapInjector。
下一节:Scroll组件之Scrollbar