Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 342
Hitesh Danidhariya Avatar asked Feb 24 '20 10:02

Hitesh Danidhariya


People also ask

How do I use setState in widget Flutter?

setState method Null safety Notify the framework that the internal state of this object has changed. Whenever you change the internal state of a State object, make the change in a function that you pass to setState: setState(() { _myState = newValue; }); The provided callback is immediately called synchronously.

Why do you need to call setState (() }) in a StatefulWidget when changing some internal data )?

setState is a way to dynamically change the UI. We call it inside the State Object class of the StatefulWidget. Calling setState marks the corresponding Widget dirty .

Does setState rebuild widget?

7. setState() The 'setState()' method is called often from the Flutter framework itself and from the developer. It is used to notify the framework that "data has changed", and the widget at this build context should be rebuilt.

How do you use setState in a class in Flutter?

When you change the state of a Stateful Widget, use setState() to cause a rebuild of the widget and its descendants. You don't need to call setState() in the constructor or initState() of the widget, because build() will be run afterward anyway. Also don't call setState() in synchronous code inside build().


Video Answer


2 Answers

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');
                  },
                ),*/
              ],
            ),
          )),
    );
  }
like image 98
Vrushi Patel Avatar answered Sep 19 '22 01:09

Vrushi Patel


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.

like image 39
aligator Avatar answered Sep 23 '22 01:09

aligator