Search code examples
androiddartflutterflutter-layout

Flutter - Add new Widget on click


I'm new to flutter and I'm trying to build a rather simple app. I have this simple (and still in progress) code and I'm trying to add a new Widget every time the user clicks a button.

Here's my code:

class ResponsavelProfilePage extends StatefulWidget {
  @override
  _ResponsavelProfilePageState createState() => new _ResponsavelProfilePageState();
}

class _ResponsavelProfilePageState extends State<ResponsavelProfilePage> {

  int _count = 1;

  @override
  Widget build(BuildContext context) {
    List<Widget> _contatos = new List.generate(_count, (int i) => new ContactRow());

    return new Scaffold(
        appBar: new AppBar(
          title: new Text(GlobalConstants.appName),
        ),
        body: new LayoutBuilder(builder: (context, constraint) {
          final _maxHeight = constraint.biggest.height / 3;
          final _biggerFont = TextStyle(fontSize: _maxHeight / 6);

          return new Center(
            child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new TextFormField(
                  decoration: new InputDecoration(
                    labelText: 'Nome',
                  ),
                ),
                new Container(
                  padding: new EdgeInsets.all(20.0),
                ),
                new TextFormField(
                  decoration: new InputDecoration(
                    labelText: 'Data de nascimento',
                  ),
                ),
                new Container(
                  padding: new EdgeInsets.all(20.0),
                ),
                new Row(
                  children: _contatos,
                ),
                new FlatButton(
                    onPressed:  _addNewContactRow,
                  child: new Icon(Icons.add),
                ),
                //new ContactRow()
              ],
            ),
          );
        })
    );
  }

  void _addNewContactRow() {
    setState(() {
      _count = _count + 1;
    });
  }
}

class ContactRow extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new _ContactRow();

}

class _ContactRow extends State<ContactRow> {
  @override
  Widget build(BuildContext context) {
    return new Container(
        child:
        new Column(
            children: <Widget>[
              new TextFormField(
                decoration: new InputDecoration(
                  labelText: 'Contato',
                ),
              ),
              new Text("Tipo Contato: "),
              new DropdownButton(
                value: _currentContactType,
                items: _dropDownMenuItems,
                onChanged: changedDropDownItem,
              ),
              new Container(
                padding: new EdgeInsets.all(20.0),
              ),
            ]
        )
    );
  }

  List _contactTypes =
  ["Phone (SMS)", "Phone (Whatsapp)", "Email"];

  List<DropdownMenuItem<String>> _dropDownMenuItems;
  String _currentContactType;

  @override
  void initState() {
    _dropDownMenuItems = getDropDownMenuItems();
    _currentContactType = null;
    super.initState();
  }

  List<DropdownMenuItem<String>> getDropDownMenuItems() {
    List<DropdownMenuItem<String>> items = new List();
    for (String city in _contactTypes) {
      items.add(new DropdownMenuItem(
          value: city,
          child: new Text(city)
      ));
    }
    return items;
  }

  void changedDropDownItem(String selectedCity) {
    setState(() {
      _currentContactType = selectedCity;
    });
  }
}

I want to add another ContactRow when the user clicks that Flat Button with addNewContactRow() on onPressed. I've found the code on addNewContactRow() and the List.generate part on another question here, but I can't make it work.

Can some one please help?


Solution

  • Just replace Row with ListView.

    Also made few changes in Height/width check it out.

    The Result : enter image description here The Code :

    import 'package:flutter/material.dart';
    
    void main() => runApp(
          new MaterialApp(
            home: new ResponsavelProfilePage(),
          ),
        );
    
    class ResponsavelProfilePage extends StatefulWidget {
      @override
      _ResponsavelProfilePageState createState() =>
          new _ResponsavelProfilePageState();
    }
    
    class _ResponsavelProfilePageState extends State<ResponsavelProfilePage> {
      int _count = 1;
    
      @override
      Widget build(BuildContext context) {
        List<Widget> _contatos =
            new List.generate(_count, (int i) => new ContactRow());
    
        return new Scaffold(
            appBar: new AppBar(
              title: new Text("NonstopIO"),
            ),
            body: new LayoutBuilder(builder: (context, constraint) {
              final _maxHeight = constraint.biggest.height / 3;
              final _biggerFont = TextStyle(fontSize: _maxHeight / 6);
    
              return new Center(
                child: new Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    new TextFormField(
                      decoration: new InputDecoration(
                        labelText: 'Nome',
                      ),
                    ),
                    new Container(
                      padding: new EdgeInsets.all(20.0),
                    ),
                    new TextFormField(
                      decoration: new InputDecoration(
                        labelText: 'Data de nascimento',
                      ),
                    ),
                    new Container(
                      padding: new EdgeInsets.all(20.0),
                    ),
                    new Container(
                      height: 200.0,
                      child: new ListView(
                        children: _contatos,
                        scrollDirection: Axis.horizontal,
                      ),
                    ),
                    new FlatButton(
                      onPressed: _addNewContactRow,
                      child: new Icon(Icons.add),
                    ),
                    //new ContactRow()
                  ],
                ),
              );
            }));
      }
    
      void _addNewContactRow() {
        setState(() {
          _count = _count + 1;
        });
      }
    }
    
    class ContactRow extends StatefulWidget {
      @override
      State<StatefulWidget> createState() => new _ContactRow();
    }
    
    class _ContactRow extends State<ContactRow> {
      @override
      Widget build(BuildContext context) {
        return new Container(
            width: 170.0,
            padding: new EdgeInsets.all(5.0),
            child: new Column(children: <Widget>[
              new TextFormField(
                decoration: new InputDecoration(
                  labelText: 'Contato',
                ),
              ),
              new Text("Tipo Contato: "),
              new DropdownButton(
                value: _currentContactType,
                items: _dropDownMenuItems,
                onChanged: changedDropDownItem,
              ),
              new Container(
                padding: new EdgeInsets.all(20.0),
              ),
            ]));
      }
    
      List _contactTypes = ["Phone (SMS)", "Phone (Whatsapp)", "Email"];
    
      List<DropdownMenuItem<String>> _dropDownMenuItems;
      String _currentContactType;
    
      @override
      void initState() {
        _dropDownMenuItems = getDropDownMenuItems();
        _currentContactType = null;
        super.initState();
      }
    
      List<DropdownMenuItem<String>> getDropDownMenuItems() {
        List<DropdownMenuItem<String>> items = new List();
        for (String city in _contactTypes) {
          items.add(new DropdownMenuItem(value: city, child: new Text(city)));
        }
        return items;
      }
    
      void changedDropDownItem(String selectedCity) {
        setState(() {
          _currentContactType = selectedCity;
        });
      }
    }