GestureDetector and Radio

2.3k Views Asked by At

I would like to execute some code when I press on Radio. GestureDetector works everywhere, but not here. If you run the code bellow, you get response (print) when tapping on Text, but not when tapping on Radio (both are wrapped in same GestureDetector).

Do you have any suggestions, how to overcome this (or explanation why this happens)?

class _MyHomePageState extends State<MyHomePage> {
  int radioGroupValue = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: GestureDetector(
              onTap: () => print("GestureDetector has been tapped."),
              child: new Row(children: [
                new Radio(
                  value: 0,
                  groupValue: radioGroupValue,
                  onChanged: _handleRadioValueWkotType,
                ),
                new Text("label 1"),
                new Radio(
                  value: 1,
                  groupValue: radioGroupValue,
                  onChanged: _handleRadioValueWkotType,
                ),
                new Text("label 2"),
              ])),
        ));
  }

  void _handleRadioValueWkotType(int value) {
    setState(() {
      radioGroupValue = value;
    });
  }
}
2

There are 2 best solutions below

1
On

You can use RadioListTile widget which acts same as the radio widget, but it has extra title parameter where you can provide text which will be shown just beside the radio widget and also clicking on the title text will behaves same as clicking on radio widget itself.

RadioListTile(
              title: Text('Standard'),
              value: 1,
              groupValue: _selectedType,
              onChanged: (int value) {
                Select(value);
}),

Check out official link and example

4
On

The Radio button is already a clickable element, so you don't need to wrap it in a GestureDetector. It makes sense to wrap text that follows it in a GestureDetector, but not the button itself. One way to achieve what you want is to call some method normally onTap, but also when the value changes, which is inside the onChanged method itself used on the Radios, like so:

class _MyHomePageState extends State<HomePage> {
  int radioGroupValue = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: GestureDetector(
              onTap: () => eitherRadioTapped(),
              child: new Row(children: [
                new Radio(
                  value: 0,
                  groupValue: radioGroupValue,
                  onChanged: _handleRadioValueWkotType,
                ),
                new Text("label 1"),
                new Radio(
                  value: 1,
                  groupValue: radioGroupValue,
                  onChanged: _handleRadioValueWkotType,
                ),
                new Text("label 2"),
              ])),
        ));
  }

  void eitherRadioTapped(){
    print("Anything in the row has been tapped.");
  }

  bool _handleRadioValueWkotType(int value) {
    print("Radio has been tapped.");

    //Whatever happendeed, it was clicked, so call the extra method
    eitherRadioTapped(); 

    setState(() {
      radioGroupValue = value;
    });
    return false;
  }

You could even set the Radio's onChanged method to null on your own code, which makes the GestureDetector receive the event, but this would make the Radio grey and need other workarounds, setup separate GestureDetectors for each Radio element, which wouldn't be ideal and be less simple.