Flutter toggle Radio widget

1,835

The GestureDetector's onTap is not being called because the GestureDetector inside the Radio widget is taking priority. By default, when two GestureDetectors are competing for input, only one will "win". In this case, the winner is the one in the Radio. This article discusses "GestureArenas" and how you can allow both GestureDetectors to process input.

However, consider whether allowing the user to deselect the radio button is the correct solution. Radio buttons are designed not to be deselected once the user has selected an option. You might instead:

  • Offer a third, "I'd rather not say" option
  • Use toggleable buttons instead of a radio group
  • Use a dropdown menu instead of a radio group

See this answer for more info on the usability aspect of this.

Share:
1,835
Ricky
Author by

Ricky

Updated on December 13, 2022

Comments

  • Ricky
    Ricky 11 months

    I'm using Radio widgets to set the user gender. These Radio button widgets are designed very well to handle the selection changes act accordingly, but I does not find a solution to somehow deselect one already selected option. I would like the gender radio group to be optional. But after user selects let's say female, he/she can change the selection to male, but can't deselect the female/male option. (So that none of the option is selected.)

    There is only an onChanged property and it only changes if the gender changes. No such thing like onTap or something similar. So no matter if I check that gender if it's the same, onChanged won't be called.

    For that reason I tried to use a GestureDetector which should solve this issue (with this I should be able to deselect the already selected option) but in case of radio widgets it does not work. I also tried to change it's behavior property but it did not help either.


    Here is the function which I use to create gender radio option with a text in a Row.

    Widget _buildRadioWithText(final genderChangeNotifier, final Gender genderParam, final String genderText) {
        return Row(
          children: <Widget>[
            GestureDetector(
              behavior: HitTestBehavior.translucent,
              child: Radio<Gender>(
                visualDensity: VisualDensity.compact,
                value: genderParam,
                groupValue: genderChangeNotifier.gender,
                onChanged: (Gender gender) {
                  genderChangeNotifier.gender = gender;
                  print(gender.toString());
                },
              ),
              onTap: () {
                if (genderChangeNotifier.gender == genderParam) {
                  genderChangeNotifier.gender = Gender.NA;
                  print("Not answered!");
                }
              },
            ),
            GestureDetector(
              onTap: () {
                if (genderChangeNotifier.gender == genderParam) {
                  genderChangeNotifier.gender = Gender.NA;
                  print("Not answered!");
                } else {
                  genderChangeNotifier.gender = genderParam;
                  print(genderParam.toString());
                }
              },
              child: Text(
                genderText,
                style: TextStyle(
                  fontSize: _fontSize,
                ),
              ),
            ),
          ],
        );
      }
    


    Function call:

    _buildRadioWithText(genderChangeNotifier, Gender.FEMALE, "Female"),
    _buildRadioWithText(genderChangeNotifier, Gender.MALE, "Male"),
    


    genderChangeNotifieris just a provider to set and get the Gender value and notify listeners when a Gender is set.

    final GenderNotifier genderChangeNotifier= Provider.of<GenderNotifier>(context);
    

    GestureDetector's onTap works well when I tap on the Text widget. It selects then deselects the option just as I'd like to but in case of the Radio widget onTap is never called.


    Any idea how to achieve the deselection when I tap/click on the Radio widget itself? And why the GestureDetector that wraps the Radio does not register the tap events?

  • Ricky
    Ricky over 3 years
    Do you think I should create an option for gender type other/custom like Facebook does? Or providing a Rather not say option instead is enough? Or use both? I know it's a question of preference but it's strange for me.
  • Bryson Thill
    Bryson Thill over 3 years
    Well, first ask yourself why you need the user's gender. The way you use the data might guide your decision. Do you even need the data at all? Are you asking so you know what pronouns to use (him/her/their)? If you don't need the data, you can eliminate the field entirely and simplify your UI. If you need to refer to them using pronouns, maybe directly ask which pronouns they prefer. I think if you do choose to give them a list of gender options, including an other/custom option is useful so you don't force anyone to choose an option that doesn't make sense for them.