在Flutter中,ScrollController可以精确地控制和管理滚动行为。通过ScrollController,可以监听滚动的位置、速度,甚至可以在用户滚动时触发自定义的动作。此外,ScrollController还提供了对滚动位置的直接控制,可以编程地滚动到特定位置。
ScrollController构造函数
ScrollController({
double initialScrollOffset = 0.0,
this.keepScrollOffset = true,
this.debugLabel,
this.onAttach,
this.onDetach,
}) : _initialScrollOffset = initialScrollOffset {
if (kFlutterMemoryAllocationsEnabled) {
ChangeNotifier.maybeDispatchObjectCreation(this);
}
}
ScrollController
常用的属性和方法
- offset:可滚动组件当前的滚动位置。
- jumpTo(double offset)、animateTo(double offset, {required Duration duration, required Curve curve,}):这两个方法用于跳转到指定的位置,它们不同之处在于,后者在跳转时会执行一个动画,而前者不会。
滚动监听
ScrollController间接继承自Listenable,可以根据ScrollController来监听滚动事件
final ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
_scrollController.addListener(() {
});
}
实例
创建一个ListView
,当滚动位置发生变化时,记录滑动位置:
final ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
_scrollController.addListener(() {
print("location:${_scrollController.offset}");
setState(() {
offset = _scrollController.offset;
});
});
}
body: ListView(
scrollDirection: scrollDirection,
controller: _scrollController,
children: randomList.map<Widget>((data) {
return Padding(
padding: const EdgeInsets.all(8),
child: _getRow(data[0], math.max(data[1].toDouble(), 50.0)),
);
}).toList(),
)
TextButton(
onPressed: () {
},
child: Text("position: ${offset.floor()}"),
)
通过animateTo方法回到顶部。
TextButton(
onPressed: () {
_scrollController.animateTo(0,
duration: const Duration(seconds: 1),//动画时间是1秒,
curve: Curves.bounceInOut);//动画曲线
},
child: Text("回到顶部"),
)
滚动位置恢复 (copy 6.4 滚动监听及控制 | 《Flutter实战·第二版》 (flutterchina.club))
PageStorage是一个用于保存页面(路由)相关数据的组件,它并不会影响子树的UI外观,其实,PageStorage是一个功能型组件,它拥有一个存储桶(bucket),子树中的Widget可以通过指定不同的PageStorageKey来存储各自的数据或状态。
每次滚动结束,可滚动组件都会将滚动位置offset存储到PageStorage中,当可滚动组件重新创建时再恢复。如果ScrollController.keepScrollOffset为false,则滚动位置将不会被存储,可滚动组件重新创建时会使用ScrollController.initialScrollOffset;ScrollController.keepScrollOffset为true时,可滚动组件在第一次创建时,会滚动到initialScrollOffset处,因为这时还没有存储过滚动位置。在接下来的滚动中就会存储、恢复滚动位置,而initialScrollOffset会被忽略。
当一个路由中包含多个可滚动组件时,如果你发现在进行一些跳转或切换操作后,滚动位置不能正确恢复&#