Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dispose/recreate a Widget after an action

Tags:

flutter

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.

enter image description here

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!"),
                  ),
                ])
        )
    );
  }
like image 504
Shady Aziza Avatar asked Sep 19 '17 03:09

Shady Aziza


1 Answers

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.

like image 197
Collin Jackson Avatar answered Oct 19 '22 02:10

Collin Jackson