1

I am trying in vain to add onLongPress to an image button along with onPressed. I get error: The named parameter 'onDoubleTap' isn't defined.

I have multiple rows of 2 horizontal image buttons using rows and expanded. Everything works except onLongPress (or onDoubleTap). What am I doing wrong, do I have to rebuild the entire code in a different format, or am I overcomplicating this?

I also tried to add a new child (error: already defined), GestureDetector, InkWell, with no success.

body: SingleChildScrollView(
      child: Container(
        child: Column(
          children: <Widget>[
            Center(
                child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                  Expanded(
                      child: FlatButton(               
                          onPressed: () {
                            setState(() {
                              launchURL();
                            });
                          },  

                          //Trying to add onLongPress , error: "onLongPress not defined
                          //If I try add a new child it says child already defined

                          onLongPress: () => _showAlertMessage(context, "message"),


                          padding: EdgeInsets.all(6.0),
                          child: Image.asset(
                            'images/image1.png',
                          ))),

                  Expanded(
                      child: FlatButton(                     
                          onPressed: () {
                            setState(() {
                              launchURL();
                            });
                          },
                          padding: EdgeInsets.all(6.0),
                          child: Image.asset(
                            'images/image2.png',
                          )
                      )//flat button
                  ),//expanded
                ])), //row-center

                //Repeat above for rows of 2 more image buttons

The code runs with a single onPressed for each button and does not display any errors, but adding any second click event displays errors.

1737973
  • 159
  • 18
  • 42
Mark
  • 83
  • 1
  • 8

4 Answers4

1

Flatbutton only supports the onPressed callback, not onLongpressed, etc. Suggest you re-look at using gesture detector or other widgets that support long press. I would try using two containers, each wrapped in a gesture detector widget, as children in the row. Each container having a text and/or image content. You can then pick up onTap, double tap, long press, etc on each container. Not tested this as I am on my phone but should work. They are probably more elegant widgets to use than container.

GrahamD
  • 2,952
  • 3
  • 15
  • 26
0

Thanks for the feedback, really appreciated. I replaced flatButton with Gesture detector inside a column, used onTap instead of onPressed, put image in new Column, added onLongPress. The code runs. When I added the second Expanded I got this error:

E/InputMethodManager( 7133): prepareNavigationBarInfo() rootView is null

I read here that "RootView is the View in which all the other views are placed. It is like the root node in a tree structure which is the parent to all the children.", but I can't see my mistake here. I did a full restart and that error is gone.

            Container(
            child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
              Expanded(
                child: GestureDetector(
                    onLongPress: () {
                      setState(() {
                        _showAlertMessage(context, "message");
                      });
                    },
                    onTap: () {
                      setState(() {
                        _launchUrl;
                      });
                    },
                    child: Container(
                        padding: EdgeInsets.all(6.0),
                        child: Image.asset(
                          'images/image1.png',
                        ) 
                        )),
              ), //Expanded

              Expanded(
                child: GestureDetector(
                    on: () {
                      setState(() {
                        _showAlertMessage(context, "message");
                      });
                    },
                    onTap: () {
                      setState(() {
                        _launchUrl;
                      });
                    },
                    child: Container(
                        padding: EdgeInsets.all(6.0),
                        child: Image.asset(
                          'images/image2.png',
                        ) 
                        )),
              ), 


            ])), 
Mark
  • 83
  • 1
  • 8
  • In your second expanded under `GestureDetector` you have an `on:` statement. This does not exist for `GestureDetector`. Please refer to the documentation for what `GestureDetector` supports. May I ask, are you using an IDE to code or a plain text editor? If the latter, I would suggest you look at using VSCode with the Flutter and Dart extensions installed. That will help you avoid mistakes like this. Hovering over eg.`GestureDetector` will immediately show you what it supports. Finally, I don't think you need to call `setState` each time. If this helps, please tick my answer as accepted. – GrahamD Sep 06 '19 at 08:06
  • I'm using Intellij it doesn't have a hover-over the widget feature that I can find. I'm a (struggling) self taught learner trying to figure out the many nuances for what I want to do. I thought I had to use set state() because I'm also connecting the GestureDetector with a TextEdtingController, but I removed them and the app runs without issue.Thanks for your help. – Mark Sep 06 '19 at 16:45
  • Hi Mark, I know your pain :-) I am also self taught (still a LOT to learn) and I am a year in. I started Flutter with a Udemy course. Spent many hours on Google and Stackoverflow.com. Do yourself a favour and use VSCode with the Flutter / Dart extensions, also Better Brackets, and several others. It is easy the learn. – GrahamD Sep 06 '19 at 16:53
  • hmm, I just read that gestureDetector 'disposes of the recognizers'. I'm not sure if this is good practice, but with GestureDetector can the text in the TextEditingController stay "alive" in the textfield if the user clicks out of the app (via URLauncher) then returns? I'm trying to keep their initial text input in the form. – Mark Sep 06 '19 at 17:01
  • Not something I have tried. Maybe someone else can guide you... otherwise it is 'try it and see' – GrahamD Sep 06 '19 at 17:09
  • Actually now I realize the gestureDetector and textEditingController are completely separate widgets. Like I said, I'm struggling ). I guess saving the controller text is completely unrelated to Gest.Det. – Mark Sep 06 '19 at 17:12
  • I would expect so. Good luck. – GrahamD Sep 06 '19 at 17:13
0

NOTE: As version 2 of flutter FlatButton is deprecated. You should use TextButton instead.

I don't know how you are using the GestureDetector but it's the best solution fit for your question and supports different aspects of user press Gestures. So I prepared the sample code below to see how it works.

        body: SingleChildScrollView(
        child: Container(
            child: Column(children: <Widget>[
  Center(
      child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
        Expanded(
            child: GestureDetector(
              onTap: () => print('onTap'), 
              onLongPress: () => print('onLongPress'), 
              onDoubleTap: () => print('onDoubleTap'), 
              child: Image.network(
              'https://lp-cms-production.imgix.net/image_browser/social-beast-GettyRF_136327669.jpg?auto=format&fit=crop&sharp=10&vib=20&ixlib=react-8.6.4&w=850&q=50&dpr=2'),
            ) //flat button
        ),

        Expanded(
            child: GestureDetector(
              onTap: () => print('onTap'), 
              onLongPress: () => print('onLongPress'), 
              onDoubleTap: () => print('onDoubleTap'), 
              child: Image.network(
              'https://lp-cms-production.imgix.net/image_browser/lions-hunting-500pxRF_7416880.jpg?auto=format&fit=crop&sharp=10&vib=20&ixlib=react-8.6.4&w=850&q=50&dpr=2'),
            )
        ), //expanded
      ])
  ), //row-center
]
            )
        )
    )

There are yet so many other gestures for GestureDetector that can be found here.

Taba
  • 3,850
  • 4
  • 36
  • 51
0

You can use InkWell widget

child: InkWell(
                                onLongPress: () {
                                  setState(() {
                                    tip++;
                                  });
                                },
                                child: FloatingActionButton(
                                  heroTag: "btn+",
                                  onPressed: () {
                                    setState(() {
                                      tip++;
                                    });
                                  },
                                  backgroundColor: Colors.grey.shade400,
                                  child: Icon(
                                    Icons.add,
                                    color: Colors.black,
                                  ),
                                ),
                              ),