You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:45:01