CustomScrollView 解决多 ListView 嵌套问题
Flutter 通过 CustomScrollView
解决多 ListView
嵌套时滑动效果不一致的问题。CustomScrollView
将多个独立的可滚动 Widget(称为 Sliver
)统一管理,确保滚动状态一致。
SliverList
替代ListView
,SliverAppBar
替代AppBar
,所有Sliver
的滚动状态由CustomScrollView
统一协调。CustomScrollView
的slivers
参数接收一个Sliver
列表,按顺序处理它们的布局和滚动逻辑。
实现视差滚动效果
视差滚动通过 SliverAppBar
和 SliverList
联动实现,背景和列表以不同速度滚动。
CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: Text('视差滚动示例'),
floating: true,
flexibleSpace: Image.network("https://xx.jpg", fit: BoxFit.cover),
expandedHeight: 300,
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(title: Text('条目 $index')),
childCount: 100,
),
),
],
);
使用 ScrollController 控制滚动
ScrollController
用于监听滚动位置和控制滚动行为,例如返回列表顶部。
class MyAppState extends State<MyApp> {
ScrollController _controller;
bool showTopButton = false;
@override
void initState() {
_controller = ScrollController();
_controller.addListener(() {
setState(() {
showTopButton = _controller.offset > 1000;
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
ElevatedButton(
onPressed: showTopButton
? () => _controller.animateTo(0, duration: Duration(milliseconds: 200), curve: Curves.ease)
: null,
child: Text('返回顶部'),
),
Expanded(
child: ListView.builder(
controller: _controller,
itemCount: 100,
itemBuilder: (context, index) => ListTile(title: Text('索引: $index')),
),
),
],
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
监听滚动事件
通过 NotificationListener
监听滚动开始、更新和结束事件。
NotificationListener<ScrollNotification>(
onNotification: (notification) {
if (notification is ScrollStartNotification) {
print('滚动开始');
} else if (notification is ScrollUpdateNotification) {
print('滚动更新');
} else if (notification is ScrollEndNotification) {
print('滚动结束');
}
return true;
},
child: ListView.builder(
itemCount: 100,
itemBuilder: (context, index) => ListTile(title: Text('条目 $index')),
),
);
关键点总结
- 统一管理滚动状态:
CustomScrollView
确保多个Sliver
的滚动效果同步。 - 视差滚动实现:
SliverAppBar
与SliverList
联动,通过flexibleSpace
设置背景图。 - 精确滚动控制:
ScrollController
用于监听位置和触发滚动动画。 - 事件通知机制:
NotificationListener
捕获滚动事件,实现更复杂的交互逻辑。