1

The Problem

I need to detect when a dropdown button was tapped so that I can remove focus from some TextFields in my view.

What I have done so far

I tried to propagate a tap event through a GestureDetector to the DropdownButton. But the HitTestBehavior does not work as mentioned in the docs.

class MainApplication extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeView(),
    );
  }
}

class HomeView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Data'),
      ),
      body: Center(
        child: Stack(
          children: [
            DropdownButton<String>(
              onChanged: (value) => print(value),
              items: ['Apple', 'Orange', 'Carrot'].map((item) {
                return DropdownMenuItem<String>(
                  child: Text(item),
                  value: item,
                );
              }).toList(),

            ),
            Positioned.fill(
              child: GestureDetector(
                behavior: HitTestBehavior.translucent,
                onTap: () {
                  print('Tapped GD');
                },
                child: Container(
                  color: Colors.green.withAlpha(60),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Ideal Result

When I tap on the button, the onTap callback should fire and the dropdown should expand simulaneously.

Ajil O.
  • 6,562
  • 5
  • 40
  • 72
  • Does this answer your question? [How to pass Taps to widgets below the top widget?](https://stackoverflow.com/questions/57929582/how-to-pass-taps-to-widgets-below-the-top-widget) – Ovidiu Feb 11 '20 at 09:25
  • @Ovidiu. Thanks for the link. For the sake of MVCE I had replaced my DropdownButton with a raised button. My use case is more specific that the drop needs to expand when I tap on the Gesture Detector and I am not sure if the linked answer does that. – Ajil O. Feb 11 '20 at 10:08
  • You still need to use the same mechanism to figure out whether the tap should have triggered the DropdownButton. You'll then additionally need to actually invoke it, as per https://stackoverflow.com/questions/57529394/how-to-open-dropdownbutton-when-other-widget-is-tapped-in-flutter – Ovidiu Feb 11 '20 at 10:26

1 Answers1

0

You can move the DropdownButton to the top of the Stack so it can detect the tap and display the dropdown items. Then you may want to consider moving the onTap function to the DropdownButton instead since you're tapping on it anyway.

class HomeView extends StatelessWidget {
  const HomeView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Data'),
      ),
      body: Center(
        child: Stack(
          children: [
            Positioned.fill(
              child: Container(
                color: Colors.green.withAlpha(60),
              ),
            ),
            DropdownButton<String>(
              onTap: () {
                print('Tapped GD');
              },
              onChanged: (value) => print(value),
              items: ['Apple', 'Orange', 'Carrot'].map((item) {
                return DropdownMenuItem<String>(
                  child: Text(item),
                  value: item,
                );
              }).toList(),
            ),
          ],
        ),
      ),
    );
  }
}
Omatt
  • 8,564
  • 2
  • 42
  • 144