'Return a new widget on button click on the same page, in a column in Flutter

I want to return a new widget on button click on the same page, in a column. So I am trying to return a container on the same page as one of the children in a column, when a button is clicked.

This is my sample code:

Column(
      children: <Widget>[
       // here I want to return my container in the show function

        Text(
          "This is a sample text",
          style: TextStyle(fontSize: 40),

        ),
        RaisedButton(
          child: Text("click"),
          onPressed: () {
            debugPrint("clicked");
            show();
          },
        )
      ],
    );



show() {
    return SampleContainer();
  }



class SampleContainer extends StatefulWidget {
  @override
  _SampleContainerState createState() => _SampleContainerState();
}

class _SampleContainerState extends State<SampleContainer> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text("hi"),


);
  }
}


Solution 1:[1]

You could use the Visibility class

Here's a full example how you can do it.

class VisibiltyExampleContainer extends StatefulWidget {
  const VisibiltyExampleContainer({
    Key key,
  }) : super(key: key);

  @override
  _VisibiltyExampleContainerState createState() =>
      _VisibiltyExampleContainerState();
}

class _VisibiltyExampleContainerState extends State<VisibiltyExampleContainer> {
  var _showContainer;

  @override
  void initState() {
    _showContainer = false;
    super.initState();
  }

  void show() {
    setState(() {
      _showContainer = !_showContainer;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
          child: Container(
        child: Column(
          children: <Widget>[
            Visibility(
              child: SampleContainer(),
              visible: _showContainer,
            ),
            Text(
              "This is a sample text",
              style: TextStyle(fontSize: 40),
            ),
            RaisedButton(
              child: Text("click"),
              onPressed: () {
                debugPrint("clicked");
                show();
              },
            )
          ],
        ),
      )),
    );
  }
}

Solution 2:[2]

create a variable

bool showContainer=false;

Then a Column Widget as

Column(
      children: <Widget>[
       // here I want to return my container in the show function

            Text(
              "This is a sample text",
              style: TextStyle(fontSize: 40),

            ),
            if(showContainer)
              SampleContainer(),
            RaisedButton(
              child: Text("click"),
              onPressed: () {
                debugPrint("clicked");
                setState () {
                 showContainer=true;
                }
              },
            )
          ],
        );

Solution 3:[3]

As an alternative to answer by dev. You can use this approach to add a widget everytime you click the button:


class Demo extends StatefulWidget {
  @override
  _DemoState createState() => _DemoState();
}

class _DemoState extends State<Demo> {
  List<Widget> widgets = List<Widget>();

  @override
  void initState(){
    widgets = <Widget>[
      Text(
        "This is a sample text",
        style: TextStyle(fontSize: 40),
      ),
      RaisedButton(
        child: Text("click"),
        onPressed: () {
          debugPrint("clicked");
          debugPrint('widgets: $widgets');
          widgets.insert(0, SampleContainer());
          setState(() {});
        },
      )
    ];
  }
  @override
  Widget build(BuildContext context) {

    return Center(
      child: Column(
        children: widgets,
      ),
    );
  }
}

show() {
  return SampleContainer();
}

class SampleContainer extends StatefulWidget {
  @override
  _SampleContainerState createState() => _SampleContainerState();
}

class _SampleContainerState extends State<SampleContainer> {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      child: Text(
        "This is an additional Widget!!",
        style: TextStyle(fontSize: 40),
      ),
    );
  }
}

Solution 4:[4]

Do not use RaisedButton or IconButton, instead put it inside a builder like this:

Builder(
              builder: (context) => Tooltip( message: "Options",
                child: IconButton(
                  icon: Icon(Icons.menu, color: Colors.white,),
                  onPressed: (){

                    showBottomSheet(context: context, builder: (context){
                      return Container(
                        color: Colors.orange,
                        height: 50,
                        width: 400,
                        child: Text("Text here"),
                      );
                    });
                  },
                ),
              ),
            ),

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Slah Layouni
Solution 2
Solution 3 Harshvardhan Joshi
Solution 4