Stack 中 ListView 顶部的 GestureDetector 会阻止滚动 - Flutter Web

GestureDetector on top of a ListView in a Stack blocks the scroll - Flutter Web

我有一个 Stack,其中首先包含一个 ListView,然后是一个带有 GestureDetector 的透明 Widget,可以单击它。一切正常,但是当我将鼠标放在 GestureDetector 中时,我无法再滚动 ListView,即使将 GestureDetector 的 behavior 属性 设置为 HitTestBehavior.translucent.

我理解这是因为 GestureDetector 正在吸收它,可能作为拖动事件,但我希望它只检测点击事件并让滚动事件“通过”。我怎样才能在 Flutter 中实现这种行为?

请注意,它仅在使用触控板(我猜是滚轮)滚动时发生,但如果您使用拖放手势滚动列表,则即使您的鼠标悬停在顶部小部件上,滚动也不会停止。

我制作了一个 DartPad,所以你可以在这里 link 自己测试一下:https://dartpad.dev/8d68891da69d661a8129d5adc7727e4c

代码也贴在下面:

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: WhosebugExample()
    ));
}

class WhosebugExample extends StatelessWidget {
  Widget _buildListItem() {
    return Container(
      margin: const EdgeInsets.symmetric(vertical: 10),
      height: 100,
      color: Colors.blue[100],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          ListView.builder(
            itemCount: 20,
            itemBuilder: (_, __) => _buildListItem(),
          ),
          Center(
            child: GestureDetector(
              behavior: HitTestBehavior.translucent,
              onTap: () => print('tap'),
              child: const Text(
                'Hover me and\ntry to scroll\nthe listview',
                style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

问题不在于 GestureDetector。实际上,文本小部件是阻止 ListView 接收指针事件的小部件。不过,您可以使用 IgnorePointer.

轻松修复它

IgnorePointer

A widget that is invisible during hit testing.

这将使文本小部件忽略指针事件并让 ListView 接收它们:

GestureDetector(
  behavior: HitTestBehavior.translucent,
  onTap: () => print('tap'),
  child: IgnorePointer( // You insert it right here above the Text widget
    child: const Text(
      'Hover me and\ntry to scroll\nthe listview',
      style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
    ),
  ),
)