When drag the GestureDetector in vertical direction in the ListView, can not trigger the GestureDetector onPanUpdate event

5,424

Check this out: Receive “onVerticalDragUpdate” on nested “GestureDetectors” in Flutter

In your case you also have horizontal drag, so you can do something like this:

class DragState extends State<Drag> {
  double x = 0, y = 0;

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: x,
      top: y,
      child: RawGestureDetector(
        gestures: {
          AllowMultipleHorizontalDragGestureRecognizer:
          GestureRecognizerFactoryWithHandlers<
              AllowMultipleHorizontalDragGestureRecognizer>(
                () => AllowMultipleHorizontalDragGestureRecognizer(),
                (AllowMultipleHorizontalDragGestureRecognizer instance) {
              instance
                ..onUpdate = (details) {
                  x += details.delta.dx;
                  setState(() {});
                };
            },
          )
        },
        child: RawGestureDetector(
          gestures: {
            AllowMultipleVerticalDragGestureRecognizer:
            GestureRecognizerFactoryWithHandlers<
                AllowMultipleVerticalDragGestureRecognizer>(
                  () => AllowMultipleVerticalDragGestureRecognizer(),
                  (AllowMultipleVerticalDragGestureRecognizer instance) {
                instance
                  ..onUpdate = (details) {
                    y += details.delta.dy;
                    setState(() {});
                  };
              },
            )
          },
          child: Container(
            width: 100,
            height: 100,
            color: Colors.lightBlue,
            child: Icon(
              Icons.games,
              color: Colors.white,
              size: 30,
            ),
          ),
        ),
      ),
    );
  }
}

class AllowMultipleVerticalDragGestureRecognizer extends VerticalDragGestureRecognizer {
  @override
  void rejectGesture(int pointer) {
    acceptGesture(pointer);
  }
}

class AllowMultipleHorizontalDragGestureRecognizer extends HorizontalDragGestureRecognizer {
  @override
  void rejectGesture(int pointer) {
    acceptGesture(pointer);
  }
}
Share:
5,424
julemand101
Author by

julemand101

Professional programmer working on healthcare solutions in Denmark. In my spare time I really like programming on a lot of small projects primarily in Dart.

Updated on December 14, 2022

Comments

  • julemand101
    julemand101 over 1 year

    When drag vertical the GestureDetector in the ListView, can not trigger the GestureDetector onPanUpdate event.

    I made a gif.

    The GestureDetector onPanUpdate event just can only be triggered by dragging in the horizontal direction.

    I know Flutter has a GestureArenaManager, but how to let the GestureDetector win in the arena?

    I want to when dragging the GestureDetector, can

    The code like this.

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/gestures.dart';
    import 'package:flutter/material.dart';
    
    void main() => runApp(MaterialApp(
          title: 'hi',
          home: DemoWidget(),
        ));
    
    class DemoWidget extends StatelessWidget {
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('GestureDetector in ListView')),
          body: ListView(children: <Widget>[
            Card(
              child: Container(
                height: 500,
                child: Stack(
                  children: <Widget>[
                    Drag(),
                  ],
                ),
              ),
            ),
            Card(
              child: Container(
                height: 1000,
              ),
            ),
          ]),
        );
      }
    }
    
    class Drag extends StatefulWidget {
      @override
      DragState createState() => DragState();
    }
    
    class DragState extends State<Drag> {
      double x = 0, y = 0;
    
      @override
      Widget build(BuildContext context) {
        return Positioned(
          left: x,
          top: y,
          child: GestureDetector(
            behavior: HitTestBehavior.opaque,
            dragStartBehavior: DragStartBehavior.down,
            child: Container(
              width: 100,
              height: 100,
              color: Colors.lightBlue,
              child: Icon(
                Icons.games,
                color: Colors.white,
                size: 30,
              ),
            ),
            onPanUpdate: (details) {
              x += details.delta.dx;
              y += details.delta.dy;
              setState(() {});
            },
          ),
        );
      }
    }