Flutter - 与子组件交互时停止ListView滚动

12
我遇到了一些问题。我正在开发一个Flutter应用程序(目前在Windows上使用Android Studio的版本为0.8.2),但我似乎无法解决一个实现细节。很可能这个问题非常简单,但我希望有人能指点我正确的方向!
我的问题是:我创建了一个自定义颜色选择器小部件,它位于可滚动的ListView中。为了让用户能够正确地与颜色选择器小部件进行交互,我需要在用户拖动选择器中的颜色指针时停止ListView的滚动,但是一旦交互完成,我需要允许ListView被滚动(因此我不能只将物理属性设置为NeverScrollableScrollPhysics)。
这里是界面的截图链接。
我目前使用Listener来处理颜色选择器内的交互,但是每当用户拖动指针时,ListView也会滚动。我尝试使用GestureDetector,但是pan GestureDetector无法防止ListView滚动。我还尝试为GestureDetector添加垂直拖动处理程序,这确实可以防止ListView滚动,但是这样做会在指针移动之前添加最小拖动距离,因为GestureDetector尝试区分平移和垂直拖动。

我希望能得到任何建议或指引。谢谢!

2个回答

6

这是一个老问题,但我自己也遇到了同样的问题,这里有一个技巧:

 bool _dragOverMap = false;
  GlobalKey _pointerKey = new GlobalKey();

  _checkDrag(Offset position, bool up) {
    if (!up) {
      // find your widget
      RenderBox box = _pointerKey.currentContext.findRenderObject();

      //get offset
      Offset boxOffset = box.localToGlobal(Offset.zero);

      // check if your pointerdown event is inside the widget (you could do the same for the width, in this case I just used the height)
      if (position.dy > boxOffset.dy &&
          position.dy < boxOffset.dy + box.size.height) {
        setState(() {
          _dragOverMap = true;
        });
      }
    } else {
      setState(() {
        _dragOverMap = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(

        title: Text("Scroll Test"),
      ),
      body: new Listener(
        onPointerUp: (ev) {
          _checkDrag(ev.position, true);
        },
        onPointerDown: (ev) {
          _checkDrag(ev.position, false);
        },
        child: ListView(
          // if dragging over your widget, disable scroll, otherwise allow scrolling
          physics:
              _dragOverMap ? NeverScrollableScrollPhysics() : ScrollPhysics(),
          children: [

            ListTile(title: Text("Tile to scroll")),
            Divider(),
              ListTile(title: Text("Tile to scroll")),
            Divider(),
              ListTile(title: Text("Tile to scroll")),
            Divider(),

            // Your widget that you want to prevent to scroll the Listview 
            Container(
              key: _pointerKey, // key for finding the widget
              height: 300,
              width: double.infinity,
              child: FlutterMap(
               // ... just as example, could be anything, in your case use the color picker widget
              ),
            ),
          ],
        ),
      ),
    );
  }
}

对我来说运行良好,也许可以简化一些东西,但你懂的。


嗨,你能帮我检查一下我的一个类似问题吗?链接在这里:https://stackoverflow.com/questions/76557774/flutter-gesturedetector-onscalestart-is-not-triggered-while-being-a-child-of-lis - undefined

1

这可能对你有所帮助。

  bool _scroll = false;

  _toggleScroll() {
    _scroll = !_scroll;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
          // switch scrolling
          physics: _scroll ? NeverScrollableScrollPhysics() : ScrollPhysics(),
          children: [],
      ),
    );
  }


@Chris的回答的简化版本 - Debabrata Samal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接