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

NotificationListener如何监听DraggableScrollableNotification滚动结束

问题解答

完全可以实现,不需要在每一帧都触发方法调用。DraggableScrollableNotification自带状态字段可以直接识别交互阶段、判断滚动/拖拽操作是否完全结束。

核心判断逻辑

DraggableScrollableNotification提供了两个关键信息用来判定操作状态:

  • dragging字段:布尔类型,值为true时代表用户正按住面板拖拽,值为false时代表用户已经抬手,直接拖拽操作终止
  • extent字段:当前面板占父容器的尺寸比例,如果你开启了snap吸附效果,用户抬手后面板会自动执行吸附动画,这时候dragging已经为false但动画还在运行,需要额外判断extent是否已经稳定到配置的吸附点、或者最小/最大尺寸边界,才能认定整个滚动+吸附流程完全结束。

注意:浮点数比较需要加微小容差,不要直接用==判断,避免浮点计算精度问题导致判断失效。

完整实现代码
NotificationListener<DraggableScrollableNotification>(
  onNotification: (notification) {
    // 拖拽过程中直接返回,不执行业务逻辑
    if (notification.dragging) return false;

    // 汇总所有面板可能停止的位置
    final validStopPositions = <double>[
      _minChildSize,
      _maxChildSize,
      ..._snapSizes,
    ];

    // 校验当前位置是否已经到达停止点,容差设为0.001规避浮点精度问题
    final currentExtent = notification.extent;
    final isOperationEnd = validStopPositions.any(
      (pos) => (currentExtent - pos).abs() < 0.001,
    );

    // 只有交互完全结束时才执行业务方法
    if (isOperationEnd) {
      func.call();
    }

    return true;
  },
  child: DraggableScrollableSheet(
    initialChildSize: _initialChildSize,
    snap: true,
    snapSizes: _snapSizes,
    minChildSize: _minChildSize,
    maxChildSize: _maxChildSize,
    controller: _sheetController,
    builder: (context, controller) {
      return _customScrollView();
    },
  ),
)
额外提示
  • 如果没有开启snap吸附效果,不需要做位置校验,只要判断notification.dragging == false即可认定操作结束
  • 该方案只会在交互完全终止时触发一次业务方法,拖拽过程、吸附动画过程都不会执行额外逻辑,完全避免每帧调用带来的不必要性能开销。

内容的提问来源于stack exchange,提问作者qwerty

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:15:33