繁体   English   中英

flutter 单击按钮时创建动态 TextField

[英]flutter create dynamic TextField when button click

在此处输入图像描述

这是我的要求,当我单击“添加”按钮时,应该生成具有三个 TextField 的动态新卡片,以及如何为每个 TextField 分配动态创建的 TextEditingControllers> 或者是否有其他方法从 TextFields 中获取值?

final name1 = new TextField(
    controller: name1Controller,
    decoration: InputDecoration(
        labelText: 'Full Name', border: OutlineInputBorder()));

final age1 = new TextField(
    controller: age1Controler,
    keyboardType: TextInputType.number,
    decoration:
        InputDecoration(labelText: 'Age', border: OutlineInputBorder()));

final studyjob1 = new TextField(
    controller: study1Controller,
    decoration: InputDecoration(
        labelText: 'Study / Job', border: OutlineInputBorder()));

final person1Card = new Card(
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(15.0),
  ),
  elevation: 10,
  child: Padding(
    padding: EdgeInsets.only(top: 2.0, left: 6.0, right: 6.0, bottom: 2.0),
    child: Column(
      children: <Widget>[
        Text('Person 1'),
        SizedBox(height: 3.0),
        name1,
        SizedBox(height: 10.0),
        age1,
        SizedBox(height: 10.0),
        studyjob1,
        SizedBox(height: 10.0),
      ],
    ),
  ),
);

return Scaffold(
    appBar: AppBar(
      title: Text('New Entry'),
    ),
    body: SingleChildScrollView(
      child: Container(
        child: Container(
          color: Colors.white,
          child: Padding(
            padding: const EdgeInsets.all(15.0),
            child: Column(
              children: <Widget>[
                person1Card,
                SizedBox(
                  height: 10.0,
                ),
                saveButton
              ],
            ),
          ),
        ),
      ),
    ))
import 'package:flutter/material.dart';

void main() {
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Home(),
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(
          child: Text('Add entries'),
          onPressed: () async {
            List<PersonEntry> persons = await Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => SOF(),
              ),
            );
            if (persons != null) persons.forEach(print);
          },
        ),
      ),
    );
  }
}

class SOF extends StatefulWidget {
  @override
  _SOFState createState() => _SOFState();
}

class _SOFState extends State<SOF> {
  var nameTECs = <TextEditingController>[];
  var ageTECs = <TextEditingController>[];
  var jobTECs = <TextEditingController>[];
  var cards = <Card>[];

  Card createCard() {
    var nameController = TextEditingController();
    var ageController = TextEditingController();
    var jobController = TextEditingController();
    nameTECs.add(nameController);
    ageTECs.add(ageController);
    jobTECs.add(jobController);
    return Card(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text('Person ${cards.length + 1}'),
          TextField(
              controller: nameController,
              decoration: InputDecoration(labelText: 'Full Name')),
          TextField(
              controller: ageController,
              decoration: InputDecoration(labelText: 'Age')),
          TextField(
              controller: jobController,
              decoration: InputDecoration(labelText: 'Study/ job')),
        ],
      ),
    );
  }

  @override
  void initState() {
    super.initState();
    cards.add(createCard());
  }

  _onDone() {
    List<PersonEntry> entries = [];
    for (int i = 0; i < cards.length; i++) {
      var name = nameTECs[i].text;
      var age = ageTECs[i].text;
      var job = jobTECs[i].text;
      entries.add(PersonEntry(name, age, job));
    }
    Navigator.pop(context, entries);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: <Widget>[
          Expanded(
            child: ListView.builder(
              itemCount: cards.length,
              itemBuilder: (BuildContext context, int index) {
                return cards[index];
              },
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: RaisedButton(
              child: Text('add new'),
              onPressed: () => setState(() => cards.add(createCard())),
            ),
          )
        ],
      ),
      floatingActionButton:
          FloatingActionButton(child: Icon(Icons.done), onPressed: _onDone),
    );
  }
}

class PersonEntry {
  final String name;
  final String age;
  final String studyJob;

  PersonEntry(this.name, this.age, this.studyJob);
  @override
  String toString() {
    return 'Person: name= $name, age= $age, study job= $studyJob';
  }
}

您可以为您的controllers使用List

例如:

class PersonControllers {
    final TextEditingController name;
    final TextEditingController age;
    final TextEditingController job;

    PersonControllers(this.name, this.age, this.job);
}

然后在你的小部件中

final List<PersonControllers> personControllers = List<PersonControllers>();

在你的initState

personControllers.add(PersonController(TextEditingController(),TextEditingController(),TextEditingController());

创建一个buildCard方法:

Widget buildCard(PersonControllers controllers){
    return Card(
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(15.0),
        ),
        elevation: 10,
        child: Padding(
            padding: EdgeInsets.only(top: 2.0, left: 6.0, right: 6.0, bottom: 2.0),
            child: Column(
                children: <Widget>[
                    Text('Person 1'),
                    SizedBox(height: 3.0),
                    _buildNameField(controllers.name),
                    SizedBox(height: 10.0),
                    _buildAgeField(controllers.age),
                    SizedBox(height: 10.0),
                    _buildJobField(controllers.job),
                    SizedBox(height: 10.0),
                ],
            ),
        ),
    );
}

最后在您的build方法中:

return Scaffold(
    appBar: AppBar(
      title: Text('New Entry'),
    ),
    body: SingleChildScrollView(
      child: Container(
        child: Container(
          color: Colors.white,
          child: Padding(
            padding: const EdgeInsets.all(15.0),
            child: Column(
              children: <Widget>[
                ...personControllers.map((personController) => _buildCard(personController),
                SizedBox(
                  height: 10.0,
                ),
                RaisedButton(
                     child: Text("Add"),
                     onPressed: (){
                         setState((){
                             personControllers.add(PersonController(
                                 TextEditingController(),
                                 TextEditingController(),
                                 TextEditingController()
                            });
                        );
                     }
                 ),
              ],
            ),
          ),
        ),
      ),
    ))

如果您还想删除表格,请查看此代码可能对某人有帮助

class Test extends StatefulWidget {
const Test({Key? key}) : super(key: key);

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

class _TestState extends State<Test> {
    var nameTECs = <int, TextEditingController>{};
 var mailTECs = <int, TextEditingController>{};
 List<Entry> entries = [];

 var item = <int, Widget>{};

 GlobalKey<FormState> _formKey = GlobalKey<FormState>();

   @override
  void didChangeDependencies() {
   super.didChangeDependencies();
   item.addAll({0: newMethod(context, 0)});
    }

  ondDone() {
  entries.clear();
   print(nameTECs.keys.last);
   for (int i = 0; i <= nameTECs.keys.last; i++) {
  var name = nameTECs[i]?.value.text;
  var mail = mailTECs[i]?.value.text;

  // print(mailTECs[i]?.value.text);
  if (name != null && mail != null) {
    entries.add(Entry(name, mail));
  }

}
print(entries);
for (int a = 0; a < entries.length; a++) {
  
  print(entries[a].name);
  print(entries[a].email);
}
 }

     newMethod(
       BuildContext context,
       int index,
       ) {
    var nameController = TextEditingController();
   var mailController = TextEditingController();
  nameTECs.addAll({index: nameController});
mailTECs.addAll({index: mailController});
return Column(
  children: [
    Text(index.toString()),
   TextFormField(
      controller: nameController,
      validator: (value) {
        return value!.isEmpty ? 'Enter some text' : null;
      },
      textFieldType: TextFieldType.NAME,
    
    ),
  
    TextFormField(
      controller: mailController,
      validator: (value) {},
      // controller: nameCount,
      textFieldType: TextFieldType.NAME,
    
    ),
    Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        FlatButton(
          onTap: () {
            item.addAll({item.keys.last+1: newMethod(context, item.keys.last + 1)});
            setState(() {});

            // }
          },
       
          child: Text('Add'),
        ),
        FlatButton(
          onTap: () {
            setState(() {
              item.removeWhere((key, value) => key == index);
              nameTECs.removeWhere((key, value) => key == index);
              mailTECs.removeWhere((key, value) => key == index);
            });
          },
        
          child: Text('Remove'),
        ),
      ],
    ),
  ],
);
}

 @override
  Widget build(BuildContext context) {
print('build');
return Scaffold(
  appBar: AppBar(
    title: Text('Test'),
  ),
  body: SingleChildScrollView(
    child: Form(
      key: _formKey,
      child: Column(
        children: [
       

          ListView.builder(
              shrinkWrap: true,
              physics: ScrollPhysics(),
              itemCount: item.length,
              itemBuilder: (context, index) {
                return item.values.elementAt(index);
              }),

          // for (int i = 0; i < widgeta.length; i++) widgeta[i],
          AppButton(
            onTap: () {
              if (_formKey.currentState!.validate()) {
                ondDone();
                // _formKey.currentState!.save();
                setState(() {});
              }
            },
            color: appPrimaryColor,
            child: Text('save'),
          ),
          Center(
            child: Text('Test', textDirection: TextDirection.rtl),
          ),
        ],
         ),
       ),
     ),
   );
   }
   }

    class Entry {
   final String? name;
  final String? email;

    Entry(
   this.name,
  this.email,
  );


  }

在此处输入图像描述

class _View4 extends StatefulWidget {
     @override
    _View4State createState() => _View4State();
}

class _GroupControllers {
  TextEditingController name = TextEditingController();
  TextEditingController tel = TextEditingController();
  TextEditingController address = TextEditingController();
  void dispose() {
    name.dispose();
    tel.dispose();
    address.dispose();
  }
}

class _View4State extends State<_View4> {
  List<_GroupControllers> _groupControllers = [];
  List<TextField> _nameFields = [];
  List<TextField> _telFields = [];
  List<TextField> _addressFields = [];

  @override
  void dispose() {
    for (final controller in _groupControllers) {
      controller.dispose();
    }
    _okController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
          appBar: AppBar(
            title: Text("Dynamic Group Text Field2"),
          ),
          body: Column(
            children: [
              _addTile(),
              Expanded(child: _listView()),
              _okButton(context),
            ],
          )),
    );
  }

  Widget _addTile() {
    return ListTile(
      title: Icon(Icons.add),
      onTap: () {
        final group = _GroupControllers();

        final nameField = _generateTextField(group.name, "name");
        final telField = _generateTextField(group.tel, "mobile");
        final addressField = _generateTextField(group.address, "address");

        setState(() {
          _groupControllers.add(group);
          _nameFields.add(nameField);
          _telFields.add(telField);
          _addressFields.add(addressField);
        });
      },
    );
  }

  TextField _generateTextField(TextEditingController controller, String hint) {
    return TextField(
      controller: controller,
      decoration: InputDecoration(
        border: OutlineInputBorder(),
        labelText: hint,
      ),
    );
  }

  Widget _listView() {
    final children = [
      for (var i = 0; i < _groupControllers.length; i++)
        Container(
          margin: EdgeInsets.all(5),
          child: InputDecorator(
            child: Column(
              children: [
                _nameFields[i],
                _telFields[i],
                _addressFields[i],
              ],
            ),
            decoration: InputDecoration(
              labelText: i.toString(),
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(10.0),
              ),
            ),
          ),
        )
    ];
    return SingleChildScrollView(
      child: Column(
        children: children,
      ),
    );
  }

  final _okController = TextEditingController();
  Widget _okButton(BuildContext context) {
    final textField = TextField(
      controller: _okController,
      keyboardType: TextInputType.number,
      decoration: InputDecoration(
        border: OutlineInputBorder(),
      ),
    );

    final button = ElevatedButton(
      onPressed: () async {
        final index = int.parse(_okController.text);
        String text = "name: ${_groupControllers[index].name.text}\n" +
            "tel: ${_groupControllers[index].tel.text}\n" +
            "address: ${_groupControllers[index].address.text}\n";
        await showMessage(context, text, "Result");
      },
      child: Text("OK"),
    );

    return Row(
      mainAxisSize: MainAxisSize.max,
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: [
        Container(
          child: textField,
          width: 100,
          height: 50,
        ),
        button,
      ],
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM