Flutter - 点击

时间:2018-06-09 19:44:00

标签: android dart flutter flutter-layout

我是新手,我试图建立一个相当简单的应用程序。 我有这个简单(并且仍在进行中)的代码,每次用户点击按钮时我都会尝试添加新的Widget。

这是我的代码:

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;
    });
  }
}

当用户在onPressed上点击带有addNewContactRow()的Flat Button时,我想添加另一个ContactRow。 我在addNewContactRow()和List.generate部分找到了另一个问题的代码,但是我无法使其工作。

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:5)

这是一种方法

首先,让我们看看列的children属性是什么。

List<Widget> children: const <Widget> []

这是小部件的List。由于Flutter UI是用代码构建的,我们可以传递我们之前构建的子数组。无需每次都在[]声明,当您想要ColumnRow

内的动态儿童时,这很方便

在构建器中,返回包装列的Center窗口小部件。因为构建器是一个函数,所以我们可以在返回Widget之前做一些魔术。

让我们首先从一个变量中的Column本身中提取数组:

  List<Widget> extractedChildren = <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()
  ];

现在,这是你到目前为止的专栏。您现在要查看的问题是,为每个_count添加一个联系人行

因此我们进行简单的旧学校迭代,并且对于每次迭代,我们将ContactRow添加到List

  for (var i = 0; i < _count; ++i) {
    extractedChildren.add(ContactRow());
  }

在我们构建了List之后,将它作为参数传递给孩子们。

 return new Center(
    child: new Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: extractedChildren,
    ),
  );

这只是一个简单的例子。记住所有UI都是使用纯代码构建的,您可以将所有知识从代码构建应用到它。例如, 我们可以提取方法来构建Column的子级以使其更漂亮

    child: new Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: createChildren(),
    ),

现在,我们不是在builder方法中创建List,而是创建一个返回List iself的新方法

List<Widget> createChildren(){
//same code for creating the list
}

重要的是不要忘记,但是您已经在代码中使用了这一点,就是更新_count内的setState属性,以便使用新的_count重建子项

答案 1 :(得分:2)

只需用ListView替换Row。

也在高度/宽度上进行了一些更改检查。

结果: enter image description here 守则:

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;
    });
  }
}