Search code examples
fluttersetstateontap

'onTap' isn't working, After fixing the "setState() or markNeedsBuild() called during build." error


I am building the BMI calculator app, after all, it giving me "setState() or markNeedsBuild() called during build." error. so, i come up with below solution..

onTap: () {
                        WidgetsBinding.instance.addPostFrameCallback((_){
                          // This is cause of "setState() or markNeedsBuild() called during build." error.
                          setState(() {
                            selectedGender = Gender.male;
                          });
                        });
                      },

the error is gone, but buttons are not working.. (like selecting male, female etc.)

full code:

    children: <Widget>[
                  Expanded( // for Male // child,colour,cardChild are the parameters for the constructor
                    child: ReusableCard(
                      onPress: () {
                        WidgetsBinding.instance.addPostFrameCallback((_){
                          // This is cause of "setState() or markNeedsBuild() called during build." error.
                          setState(() {
                            selectedGender = Gender.male;
                          });
                        });
                      },
                      colour: selectedGender == Gender.male ? kActiveCardColour : kInactiveCardColour, // from constants.dart
                      cardChild: IconContent(
                        icon: FontAwesomeIcons.mars,
                        label: 'MALE',
                      ),
                    ),
                  ),
                  Expanded( // for Female
                    child: ReusableCard(
                      onPress: () {
                        WidgetsBinding.instance.addPostFrameCallback((_){
                          // This is cause of "setState() or markNeedsBuild() called during build." error.
                          setState(() {
                            selectedGender = Gender.female;
                          });
                        });
                      },
                      colour: selectedGender == Gender.female ? kActiveCardColour : kInactiveCardColour,
                      cardChild: IconContent(
                        icon: FontAwesomeIcons.venus,
                        label: 'FEMALE',
                      ),
                    ),
                  ),
                ],
import 'package:flutter/material.dart';
// card for male, female etc..

class ReusableCard extends StatelessWidget {

  final Color colour;
  final Widget cardChild;
  final Function onPress;

  // Constructor
  ReusableCard({required this.colour, required this.cardChild, required this.onPress});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onPress(),
      child: Container(
        child: cardChild,
        margin: EdgeInsets.all(15.0),
        // color: colour, can't use cause..  color is short-hand of from BoxDecoration
        decoration: BoxDecoration(
          color: colour,
          borderRadius: BorderRadius.circular(10.0),
        ),
      ),
    );
  }
}

code is about select make or female, the container will change properties according to onPress() but after the running the code, i presses the that containers, doesn't happen anything..


Solution

  • Using directly onTap: onPress() will call the method during build time. You can create an anonymous function/ which will trigger onPressed,

     onTap:()=> onPress(),
    

    Or You can just use VoidCallback instead of Function.

     final VoidCallback onPress;
    

    And use like onTap: onPress. No need to use postFrameCallback.