Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid duplicate events when combining GestureDetector and Listener in flutter

Tags:

flutter

In the example below we have a tappable red container inside a green container.

  • The red container is wrapped with Listener
  • The green container is wrapped with GestureDetector

Problem: when tapping the red container, BOTH the Listener and GestureDetector receive events, which is a mistake. (Only the topmost widget should get a tap event, when tapped. And only the green widget should get an event when tapped). If both wrapped with GestureDetector, only the topmost widget gets the event.

enter image description here

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
            child: Column(children: [
          // Parent-child -- two events when red is tapped
          GestureDetector(
            onTap: () {
              print("Green");
            },
            child: Container(
              color: Colors.green,
              width: 100.0,
              height: 100.0,
              child: Center(
                child: Listener(
                  behavior: HitTestBehavior.opaque,
                  onPointerDown: (_) {
                    print("Red");
                  },
                  child: Container(
                    color: Colors.red,
                    width: 50.0,
                    height: 50.0,
                  ),
                ),
              ),
            ),
          ),
        ])),
      ),
    );
  }
}
like image 529
user48956 Avatar asked Oct 29 '25 03:10

user48956


1 Answers

as an option wrap Listener with GestureDetector to prevent event bubbling

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
            child: Column(children: [
              // Parent-child -- two events when red is tapped
              GestureDetector(
                onTap: () {
                  print("Green");
                },
                child: Container(
                  color: Colors.green,
                  width: 100.0,
                  height: 100.0,
                  child: Center(
                    child: GestureDetector(
                      behavior: HitTestBehavior.opaque,
                      onTap: (){},
                      child: Listener(
                        behavior: HitTestBehavior.opaque,
                        onPointerDown: (_) {
                          print("Red");
                        },
                        child: Container(
                          color: Colors.red,
                          width: 50.0,
                          height: 50.0,
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ])),
      ),
    );
  }
}