Search code examples
fluttergesturedetectordismissible

GestureDetector is not working with Dismissible Widget


I am trying to get the drag offsets while using Dismissible widget. So tried to wrap it with GestureDetector but its onHorizontalDragStart is not working.
Tried the either way ie by putting GestureDetector as child of Dismissible but then Dismissible stopped working.
How to solve this? Thnx...

ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    var item = items[index];
    return GestureDetector(
      onHorizontalDragStart: (e) {
        print(e);
      },
      child: Dismissible(
        key: ValueKey(item),
        background: Container(
          color: Colors.teal,
        ),
        child: ListTile(
          title: Text("item $item"),
        ),
        onDismissed: (d) {
          items.remove(item);
        },
      ),
    );
  },
);

Solution

  • Nested Gesture Widgets

    The reason you are having this issue is because both of those widgets receive touch input and when you have two widgets that receive touch input, long story short the child wins that battle. Here is the long story. So both of your inputs from your Dismissible and GestureDetector are sent to what is called a GestureArena. There the arena takes into account multiple different factors but the end of the story is the child always wins. You can fix this issue by defining your own RawGestureDetector with its own GestureFactory which will change the way the arena performs.

    ListView.builder(
          physics: AlwaysScrollableScrollPhysics(),
          itemCount: items.length,
          itemBuilder: (BuildContext context, int index) {
            var item = items[index];
            return Listener(
              child: Dismissible(
                key: ValueKey(item),
                child: ListTile(
                  title: Text('This is some text'),
                ),
                onDismissed: (DismissDirection direction) {
                  items.remove(index);
                },
              ),
              onPointerMove: (PointerMoveEvent move) {
                if (move.localDelta.dx > 1) {//Ideally this number whould be 
    //(move.localDelta.dx != 0) but that is too sensitive so you can play with 
    //this number till you find something you like. 
                  print(move.position);
                }
              },
            );
          },
        );
    

    I want to give all credit to Nash the author of Flutter Deep Dive: Gestures this is a great article I highly recommend you check it out.