Zenko
Zenko

Reputation: 2559

How do I programmatically simulate onTap on a button in Flutter?

For example:

// Update: This GestureDetector is embedded inside a third party package
// that will invoke a series of animation along with the onTap button
GestureDetector(
   onTap: () => print('Hey There!'),
   child: Widget1(),
)


// Then another place in the same screen
GestureDetector(
    onDoubleTap: () { 
           //Call the onTap of Widget1's GestureDetector
           print('I'm Here');
        }
    child: Widget2(),
)

What I wanted is when a user double tap Widget2, it will also invoke the onTap call back of Widget1.

Update: So I do not want to just invoke a function passed into the onTap of GestureDetector of Widget1, but rather to programmatically tap the onTap of Widget1's GestureDetector

How do I do that?

Upvotes: 4

Views: 12558

Answers (4)

Sunil Gupta
Sunil Gupta

Reputation: 832

After several false starts, this is what worked for me. I use Riverpod, and formFocusIdProvider in this example code is a simple StateProvider.

I'm actually not clear why I needed to add the delay - but without that the behavior was unpredictable with the widget repaint.

This code is in the build method.

ref.listen(formFocusIdProvider, (previous, next) {
  if (<some condition>) {
    Future.delayed(const Duration(milliseconds: 200), () {
      if (mounted) {
        onTapFunction();
      }
    });
  }
});

Upvotes: 0

Tanuj
Tanuj

Reputation: 2260

You can do something like this -

Create your gesture detector -

   GestureDetector gestureDetector = GestureDetector(
      onTap: () {
        setState(() {
          _lights = !_lights;
        });
      },
      child: Container(
        color: Colors.yellow.shade600,
        padding: const EdgeInsets.all(8),
        child: const Text('TURN LIGHTS ON'),
      ),
    );

Create a button (or any widgetthat you would like to use) to call onTap on GestureDetector gestureDetector.onTap() just like you call method on another widget. (I am using a FlatButton here)-

          FlatButton(
            color: Colors.blue,
            textColor: Colors.white,
            disabledColor: Colors.grey,
            disabledTextColor: Colors.black,
            padding: EdgeInsets.all(8.0),
            onPressed: () {
              //Trigger the GestureDetector onTap event.
              gestureDetector.onTap();
            },
            child: Text("Click Here"),
          ),

Now you can click on the FlatButton to call the onTap event on GestureDetector.

Here is the complete example -

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Gesture Detector On Tap'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _lights = false;

  @override
  Widget build(BuildContext context) {
    GestureDetector gestureDetector = GestureDetector(
      onTap: () {
        setState(() {
          _lights = !_lights;
        });
      },
      child: Container(
        color: Colors.yellow.shade600,
        padding: const EdgeInsets.all(8),
        child: const Text('TURN LIGHTS ON'),
      ),
    );

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Container(
          alignment: FractionalOffset.center,
          color: Colors.white,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Icon(
                  Icons.lightbulb_outline,
                  color: _lights ? Colors.yellow.shade600 : Colors.black,
                  size: 60,
                ),
              ),
              gestureDetector,
              SizedBox(height: 50.0),
              FlatButton(
                color: Colors.blue,
                textColor: Colors.white,
                disabledColor: Colors.grey,
                disabledTextColor: Colors.black,
                padding: EdgeInsets.all(8.0),
                onPressed: () {
                  gestureDetector.onTap();
                },
                child: Text("Click Here"),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

You will get something like this -

enter image description here

Upvotes: 11

Bach
Bach

Reputation: 3326

Update: So I do not want to just invoke a function passed into the onTap of GestureDetector of Widget1, but rather to programmatically tap the onTap of Widget1's GestureDetector

The purpose of onTap is to call the callback function inside the onTap. So I'm not sure why you just want to tap the button other than invoking functions that should be called when tapping that button (Can you elaborate on this?).

If you want to simulate the tap for testing, you can do that with Flutter Driver using driver.tap()

Upvotes: 1

Hamza Bashir
Hamza Bashir

Reputation: 135

just make the first one's function separately

void firstFunction(){
print('hey There!');
}

like this, then call it in the second widget so your code will look like this:

GestureDetector(
   onTap: () => firstFunction(),
   child: Widget1(),
)
// Then another place in the same screen
GestureDetector(
onDoubleTap: () { 
   firstFunction();
   print('I'm Here');
}
child: Widget2(),
)

Upvotes: -1

Related Questions