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.
Author by
Hitesh Danidhariya
Updated on December 18, 2022Comments
-
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 about 4 yearsYes did the same for now. Thanks :)
-
Hitesh Danidhariya about 4 yearsAny idea about how to use keys to achieve this?
-
Vrushi Patel about 4 yearsKeys won't be of help here once parent widget build it by default rebuild children with it.
-
marlonjd about 4 yearsYou are the real hero !!! Thank you so much. It litterally save my life
-
K Pradeep Kumar Reddy over 3 yearsCan this stateless widget be called as part of stateful widget build widget tree hierarchy ??
-
blessing dickson over 3 yearsBest approach!... Works very fine. Thank you so much for this answer
-
vishalknishad about 2 yearsperfect answer.