Flutter中拖拽开始后如何编程停止滚动且不触发setState重建?
无重绘禁用滚动的实现方案
你可以通过自定义可动态控制的ScrollPhysics实现需求,全程不需要调用setState,也不会触发滚动组件及子节点的重绘。
方案实现步骤
- 自定义带控制开关的滚动物理效果类
class ControllableScrollPhysics extends ScrollPhysics { // 滚动控制开关,外部可直接修改 bool canScroll; ControllableScrollPhysics({super.parent, this.canScroll = true}); @override ControllableScrollPhysics applyTo(ScrollPhysics? ancestor) { return ControllableScrollPhysics( parent: buildParent(ancestor), canScroll: canScroll, ); } @override bool shouldAcceptUserOffset(ScrollMetrics position) => canScroll; @override bool get allowImplicitScrolling => canScroll; @override double applyPhysicsToUserOffset(ScrollMetrics position, double offset) { return canScroll ? offset : 0.0; } }
- 在组件中实例化并使用该物理效果
直接将实例化后的自定义物理类传入滚动组件的physics参数即可,不需要绑定组件状态:
// State类中声明 final _customPhysics = ControllableScrollPhysics(); final _scrollController = ScrollController(); // build方法中滚动组件配置 ListView( controller: _scrollController, physics: _customPhysics, // 其余配置不变 )
- 任意时机控制滚动开关
直接修改canScroll属性即可,无需调用setState:
// 禁用滚动 _customPhysics.canScroll = false; // 启用滚动 _customPhysics.canScroll = true;
额外补充:立即中止正在进行的滚动
如果需要在禁用滚动的同时,终止当前正在进行的惯性滚动/用户拖动行为,可以同步调用ScrollController的停止方法,同样无重绘开销:
_scrollController.position.stop(canceled: true);
内容的提问来源于stack exchange,提问作者rasitayaz
相关产品推荐
相关产品推荐

