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

Flutter稳定版Web端嵌套滚动双滚动条常显异常问题

问题原因

Flutter 2.5.0版本重构了滚动通知冒泡逻辑,嵌套滚动场景下,子垂直滚动组件的滚动通知会向上冒泡到父水平滚动组件的Scrollbar监听逻辑中。原有代码里仅通过depth == 0判断无法过滤掉方向不匹配的滚动通知,水平Scrollbar接收到垂直方向的滚动通知后会判定为非自身滚动事件,触发隐藏逻辑,导致异常。

可行解决方案

修改水平滚动组件外层Scrollbar的notificationPredicate判断规则,在深度判断的基础上增加滚动方向校验,仅响应水平方向的滚动通知即可解决该问题,修改后的核心代码如下:

Widget _buildHorizontalScroll() {
  return Scrollbar(
    // 若使用Flutter 3.0+版本,isAlwaysShown请替换为thumbVisibility
    isAlwaysShown: true,
    controller: _horizontalController,
    notificationPredicate: (notification) {
      // 仅处理深度为0、且为水平方向的滚动通知
      return notification.depth == 0 && notification.metrics.axis == Axis.horizontal;
    },
    // 原有子组件逻辑保持不变
    child: ListView.separated(
      controller: _horizontalController,
      scrollDirection: Axis.horizontal,
      itemBuilder: (context, index) => Container(
            margin: const EdgeInsets.all(30),
            width: 300,
            color: Colors.black12,
            child: Column(
              children: [
                Expanded(
                  child: _buildVerticalScroll(index),
                )
              ],
            ),
          ),
      separatorBuilder: (context, index) => const Divider(
            height: 30,
          ),
      itemCount: 6),
  );
}

如果修改后仍有异常,可在垂直滚动的ListView外层加NotificationListener,手动阻止垂直滚动通知向上冒泡,代码如下:

Widget _buildVerticalScroll(int index) {
  return NotificationListener<ScrollNotification>(
    onNotification: (notification) => true,
    child: Scrollbar(
      scrollbarOrientation: ScrollbarOrientation.right,
      // 若使用Flutter 3.0+版本,isAlwaysShown请替换为thumbVisibility
      isAlwaysShown: true,
      controller: _verticalController[index],
      child: ListView.separated(
          controller: _verticalController[index],
          itemBuilder: (context, index) => Container(
                margin: const EdgeInsets.all(30),
                height: 100,
                color: Colors.green,
              ),
          separatorBuilder: (context, index) => const Divider(
                height: 30,
              ),
          itemCount: 200),
    ),
  );
}

修改后滚动垂直列表时水平滚动条会保持常显,两个滚动条互不干扰,符合预期效果。

适配说明

  • Flutter 3.0及以上版本中,Scrollbar的isAlwaysShown属性已被标记为废弃,替换为thumbVisibility属性即可,功能完全一致。
  • 该方案不影响原有滚动逻辑,滚动性能也不会受到额外影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:06:03