I am trying to figure out how to destroy/recreate a Widget
based on an action (e.g: onPressed
).
The way I thought about this, is to have my Widget rapped within an Opacity
object, and control the state of the Opacity
object based on user interaction somewhere in my app(i.e: hide/show the widget instead of dispose/recreate ). However, what I am asking here, how to destroy/recreating a Widget after clicking a Button?
I have created the following dummy example to show what I mean.
The red Icon
should be disposed when I press the cloud Icon
and recreated when I press the RaisedButton
.
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Destroy/Recreate Example"),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Stack(fit: StackFit.passthrough,
children: <Widget>[
new IconButton(icon: new Icon(
Icons.cloud_circle, size: 40.0, color: Colors.blue,),
onPressed: null /*_destroyWidget*/),
new Positioned(child: new DecoratedBox(
decoration: new BoxDecoration(shape: BoxShape.circle),
child: new Icon(
Icons.add_circle, size: 20.0, color: Colors.red,),),
top: 3.0,
left: 3.0)
],
),
new RaisedButton(onPressed: null /*_recreateWidget*/,
child: new Text("Recreate!"),
),
])
)
);
}
How to start on this idea?
Update
The following code achieves the same thing but by manipulating the Opacity
of the red Icon
(show/hide).
var _myOpacity = 0.0;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Destroy/Recreate Example"),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Stack(fit: StackFit.passthrough,
children: <Widget>[
new IconButton(icon: new Icon(
Icons.cloud_circle, size: 40.0, color: Colors.blue,),
onPressed: ()=>setState((){
_myOpacity =0.0;
}) /*_destroyWidget*/),
new Positioned(child: new Opacity(
opacity: _myOpacity,
child:
new DecoratedBox(
decoration: new BoxDecoration(shape: BoxShape.circle),
child: new Icon(
Icons.add_circle, size: 20.0, color: Colors.red,),),),
top: 3.0,
left: 3.0)
],
),
new RaisedButton(onPressed: ()=>
setState((){
_myOpacity = 1.0;
})
/*_recreateWidget*/,
child: new Text("Recreate!"),
),
])
)
);
}
You will have to wrap your red icon in a StatefulWidget
if you want to be notified when it is initialized and disposed. A StatelessWidget
doesn't have these callbacks.
You can replace the StatefulWidget
with null in a setState
and its State
will be disposed. You can set it back to normal in a second setState
callback, and a new State
will be created and its initState
will be called.
If you want to dispose
and initState
without going through the intermediate step of having a widget be replaced with null
, try giving your StatefulWidget
a new UniqueKey
when the recreate button is pressed. This will prevent Flutter from associating the old State
with the new StatefulWidget
.
It seems like you're mostly doing this out of curiosity rather than a genuine use case. The shopping card example you've described probably doesn't need to use initState
and dispose
at all and you should just use a StatelessWidget
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With