Search code examples
flutterflutter-layoutvisibilityflutter-animation

Using Visibility Widget in Flutter to toggle widgets display


I have a Column widget I'd only like to make visible when a user taps on the add new button. I am using the Visibility widget Flutter provides and I am using setState() to change the visible property in the Visibility widget class. It doesn't work.

What could I be overlooking? Find my code snippet below:

bool _addNewTax = false;

FlatButton.icon(
    color: kBgCircleColour,
    padding: EdgeInsets.all(15.0),
    icon: Icon(
      FontAwesomeIcons.plusSquare,
      color: kThemeStyleButtonFillColour,
    ),
    onPressed: () {
      setState(() {
        _addNewTax = true;
      });
        Visibility(
          visible: _addNewTax,
          child: _buildTaxInputFields(),
        );
    },
    label: Text(
      'Add new tax',
      style: kRegularTextStyle,
    ),
  );

My _buildTaxInputFields function as below:

      _buildTaxInputFields() {
        return Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(20.0),
              child: TextFormField(
                initialValue: inputValue,
                textAlign: TextAlign.left,
                onSaved: () {},
                decoration: kTextFieldDecoration.copyWith(hintText: 'tax name e.g. VAT, service charge, etc'),
                ),
            Padding(
              padding: const EdgeInsets.all(20.0),
              child: TextFormField(
                initialValue: inputValue,
                textAlign: TextAlign.left,
                onSaved: () {},
                decoration: kTextFieldDecoration.copyWith(hintText: 'tax percentage e.g. 20, 19.5'),
                ),
            Row(
              children: <Widget>[
                Expanded(
                  flex: 1,
                  child: RadioListTile(
                    title: Text('I\'ll bear it '),
                    value: TaxBearer.merchant,
                    groupValue: _taxBearer,
                    onChanged: (TaxBearer value) {
                      setState(() {
                        _taxBearer = value;
                      });
                    },
                  ),
                ),
                Expanded(
                  flex: 1,
                  child: RadioListTile(
                      title: Text('Push to customer'),
                      value: TaxBearer.customer,
                      groupValue: _taxBearer,
                      onChanged: (TaxBearer value) {
                        setState(() {
                          _taxBearer = value;
                        });
                      }),
                ),
              ],
            ),
          ],
        );
      }

Solution

  • Your visibility widget will never be rendered because you're generating it in the onPressed method of a button. You could use a column to generate it below the button like this:

    bool _addNewTax = false;
    Column(
      children: [
       FlatButton.icon(
        color: kBgCircleColour,
        padding: EdgeInsets.all(15.0),
        icon: Icon(
          FontAwesomeIcons.plusSquare,
          color: kThemeStyleButtonFillColour,
        ),
        onPressed: () {
          setState(() {
            _addNewTax = true;
          });
        },
        label: Text(
          'Add new tax',
          style: kRegularTextStyle,
        ),
      ),
      Visibility(
        visible: _addNewTax,
        child: _buildTaxInputFields(),
      ),
     ],
    );