How to stop a widget to reload on setState() method in StatefulWidget Class in Flutter

6,941

Solution 1

Build it in initState() then use it's reference wherever required it will not build again until parent widget reinitialized.

  var banner;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    bannerSize = AdmobBannerSize.BANNER;
    banner = AdmobBannerWrapper(adUnitId: getBannerAdUnitId(),adSize: bannerSize,key:_globalKey,);
  }

than call it in by reference here banner


  @override
  Widget build(BuildContext context) {
    double height = MediaQuery.of(context).size.height;
    double width = MediaQuery.of(context).size.width;

    return new Scaffold(
      body: new Container(
          width: width,
          child: new Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                Expanded(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    mainAxisSize: MainAxisSize.max,
                    children: <Widget>[
                      Flexible(
                        child: new Hero(
                          tag: "gender",
                          child: Material(
                            child: new Row(
                              children: <Widget>[
                                InkWell(
                                  onTap: () {
                                    setState(() {
                                      if (isFemaleSelected) {
                                        isFemaleSelected = false;
                                      } else {
                                        isFemaleSelected = true;
                                      }
                                    });
                                  },
                                  child: Opacity(
                                    child: Image.asset(
                                      "assets/woman.png",
                                      height: height / 4,
                                      width: width / 2 - 12,
                                    ),
                                    opacity: isFemaleSelected ? 1.0 : 0.30,
                                  ),
                                ),
                                InkWell(
                                  onTap: () {
                                    setState(() {
                                      if (isFemaleSelected) {
                                        isFemaleSelected = false;
                                      } else {
                                        isFemaleSelected = true;
                                      }
                                    });
                                  },
                                  child: Opacity(
                                    opacity: !isFemaleSelected ? 1.0 : 0.30,
                                    child: Image.asset(
                                      "assets/boy.png",
                                      height: height / 4,
                                      width: width / 2 - 12,
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  flex: 1,
                ),
                InkWell(
                    onTap: () {
                      setState(() {

                      });
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (BuildContext) =>
                                  new HeightWeightSelection(isFemaleSelected
                                      ? "assets/woman.png"
                                      : "assets/boy.png")));
                    },
                    child: Container(
                      margin: EdgeInsets.only(bottom: 12.0),
                      child: new Image.asset(
                        "assets/next.png",
                        height: 64.0,
                        width: 64.0,
                      ),
                    )),
                banner, /*this is our variable */
               /* new AdmobBanner(
                  adUnitId: getBannerAdUnitId(),
                  adSize: bannerSize,
                  listener:
                      (AdmobAdEvent event, Map<String, dynamic> args) {
                    handleEvent(event, args, 'Banner');
                  },
                ),*/
              ],
            ),
          )),
    );
  }

Solution 2

Put it inside a stateless widget:

class AdBanner extends StatelessWidget{
  final adUnitId;
  final adSize;

  const AdBanner({Key key, this.adUnitId, this.adSize}) : super(key: key);

  Widget build(BuildContext context){
    return AdmobBannerWrapper(
      adUnitId: getBannerAdUnitId(),
      adSize: bannerSize,
      key: _globalKey,
      );
  }
}

next time when you call setState if the parameters are unchanged, it is not going to get rebuilt.

Share:
6,941
Hitesh Danidhariya
Author by

Hitesh Danidhariya

Updated on December 18, 2022

Comments

  • Hitesh Danidhariya
    Hitesh Danidhariya over 1 year

    What I am trying to achieve is to save the state of the Widget i.e it should not refresh when the setState() method is been called.

    class _GenderSelectionPageState extends State<GenderSelectionPage> {
      bool isFemaleSelected = false;
      AdmobBannerSize bannerSize;
      GlobalKey _globalKey = new GlobalKey();
    
      bool isLoaded = false;
    
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        bannerSize = AdmobBannerSize.BANNER;
      }
    
      @override
      Widget build(BuildContext context) {
        double height = MediaQuery.of(context).size.height;
        double width = MediaQuery.of(context).size.width;
    
        return new Scaffold(
          body: new Container(
              width: width,
              child: new Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    Expanded(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        mainAxisSize: MainAxisSize.max,
                        children: <Widget>[
                          Flexible(
                            child: new Hero(
                              tag: "gender",
                              child: Material(
                                child: new Row(
                                  children: <Widget>[
                                    InkWell(
                                      onTap: () {
                                        setState(() {
                                          if (isFemaleSelected) {
                                            isFemaleSelected = false;
                                          } else {
                                            isFemaleSelected = true;
                                          }
                                        });
                                      },
                                      child: Opacity(
                                        child: Image.asset(
                                          "assets/woman.png",
                                          height: height / 4,
                                          width: width / 2 - 12,
                                        ),
                                        opacity: isFemaleSelected ? 1.0 : 0.30,
                                      ),
                                    ),
                                    InkWell(
                                      onTap: () {
                                        setState(() {
                                          if (isFemaleSelected) {
                                            isFemaleSelected = false;
                                          } else {
                                            isFemaleSelected = true;
                                          }
                                        });
                                      },
                                      child: Opacity(
                                        opacity: !isFemaleSelected ? 1.0 : 0.30,
                                        child: Image.asset(
                                          "assets/boy.png",
                                          height: height / 4,
                                          width: width / 2 - 12,
                                        ),
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                      flex: 1,
                    ),
                    InkWell(
                        onTap: () {
                          setState(() {
    
                          });
                          Navigator.push(
                              context,
                              MaterialPageRoute(
                                  builder: (BuildContext) =>
                                      new HeightWeightSelection(isFemaleSelected
                                          ? "assets/woman.png"
                                          : "assets/boy.png")));
                        },
                        child: Container(
                          margin: EdgeInsets.only(bottom: 12.0),
                          child: new Image.asset(
                            "assets/next.png",
                            height: 64.0,
                            width: 64.0,
                          ),
                        )),
                    new AdmobBannerWrapper(adUnitId: getBannerAdUnitId(),adSize: bannerSize,key: _globalKey,),
                   /* new AdmobBanner(
                      adUnitId: getBannerAdUnitId(),
                      adSize: bannerSize,
                      listener:
                          (AdmobAdEvent event, Map<String, dynamic> args) {
                        handleEvent(event, args, 'Banner');
                      },
                    ),*/
                  ],
                ),
              )),
        );
      }
    

    I don't want to call the AdmobBannerWrapper every time I press my image button at the bottom.AdmobBannerWrapper should be loaded once only but the thing is whenever I click the Next Image it load AdmobBannerWrapper method every time.

  • Hitesh Danidhariya
    Hitesh Danidhariya about 4 years
    Yes did the same for now. Thanks :)
  • Hitesh Danidhariya
    Hitesh Danidhariya about 4 years
    Any idea about how to use keys to achieve this?
  • Vrushi Patel
    Vrushi Patel about 4 years
    Keys won't be of help here once parent widget build it by default rebuild children with it.
  • marlonjd
    marlonjd about 4 years
    You are the real hero !!! Thank you so much. It litterally save my life
  • K Pradeep Kumar Reddy
    K Pradeep Kumar Reddy over 3 years
    Can this stateless widget be called as part of stateful widget build widget tree hierarchy ??
  • blessing dickson
    blessing dickson over 3 years
    Best approach!... Works very fine. Thank you so much for this answer
  • vishalknishad
    vishalknishad about 2 years
    perfect answer.