Flutter - 创建动态数量的texteditingcontrollers

时间:2018-06-08 17:58:44

标签: dynamic dart flutter

我正在重新创建我之前在Swift中创建的应用程序,在我的一个页面上,我们称之为API,并根据结果,向用户显示动态数量的文本字段,以便按不同的搜索参数进行搜索。

在Dart / Flutter中有什么好办法吗?由于dart不支持在运行时生成代码,这是否可能?

5 个答案:

答案 0 :(得分:2)

正如@GünterZöchbauer所提到的,您可以构建一个嵌套在容器中的小部件列表。

这是一个简单的例子:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "MyHomePage",
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(
        title: "MyHomePage",
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final title;

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    var stringListReturnedFromApiCall = ["first", "second", "third", "fourth", "..."];

    // This list of controllers can be used to set and get the text from/to the TextFields
    var textEditingControllers = <TextEditingController>[];

    var textFields = <TextField>[];
    stringListReturnedFromApiCall.forEach((str) {
      var textEditingController = new TextEditingController(text: str);
      textEditingControllers.add(textEditingController);
      return textFields.add(new TextField(controller: textEditingController));
    });

    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: SingleChildScrollView(
            child: new Column(
          children: textFields,
        )));
  }
}

修改:添加了TextEditingController列表,以便与所有TextField

进行互动

答案 1 :(得分:1)

我刚刚使用Map存储TextEditingControllers而不是list来修改@Felix的答案。我认为使用键值对调用textEditingControllers很容易。 修改后的代码块;

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "MyHomePage",
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(
        title: "MyHomePage",
      ),
    );
  }
}
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final title;

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

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    var stringListReturnedFromApiCall = ["first", "second", "third", "fourth", "..."];
    // This list of controllers can be used to set and get the text from/to the TextFields
    Map<String,TextEditingController> textEditingControllers = {};
    var textFields = <TextField>[];
    stringListReturnedFromApiCall.forEach((str) {
      var textEditingController = new TextEditingController(text: str);
      textEditingControllers.putIfAbsent(str, ()=>textEditingController);
      return textFields.add( TextField(controller: textEditingController));
    });

    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: SingleChildScrollView(
            child: new Column(
              children:[
              Column(children:  textFields),
                RaisedButton(
                  child: Text("Print Values"),
                    onPressed: (){
                    stringListReturnedFromApiCall.forEach((str){
                      print(textEditingControllers[str].text);
                    });
                  })
              ]
            )));
  }
}

当您向文本字段中写入内容并点击以打印按钮结果时;

flutter: first controller text
flutter: second controller text
flutter: third controller text
flutter: fourth controller text
flutter: so on .......

答案 2 :(得分:0)

也许这可以帮助您或其他人。

createFieldsList(context) {
    thirdStepUserRegistration.value.forEach((key, value) { //// This line will loop all your data [ValueNotifier<Map<String, dynamic>> thirdStepUserRegistration]
      if (!fieldsController.containsKey(key)) {
        fieldsController[key] = TextEditingController(); //// This one will create you a list of controllers that u need for your fiels [Map<String, TextEditingController> fieldsController]
        fieldsList.add( ////You will be creating a list of widget which is textfields [List<Widget> fieldsList]
          Container(
            height: 40.0,
            margin: EdgeInsets.only(bottom: 10),
            width: MediaQuery.of(context).size.width - 100,
            child: PrimaryTextFormField( //This is my customize textfield you can create yours
              controller: fieldsController[key],
              keyboardType: TextInputType.text,
              textCapitalization: TextCapitalization.words,
              inputFormatters: textFormatter(),
              hintText: value,
            ),
          )
        );
      }
    });
  }

  Column additionalDetails(BuildContext context) {
    createFieldsList(context);
    return Column( children: fieldsList );
  }

答案 3 :(得分:0)

使用 textEditingControllers 列表代替地图

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final title;

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

class _MyHomePageState extends State<MyHomePage> {
  var stringListReturnedFromApiCall = ["first", "second", "third", "fourth", "..."];
  List<TextEditingController> textEditingControllers = [];

  @override
  void initState() {
    super.initState();
    stringListReturnedFromApiCall.forEach((String str) {
      var textEditingController = TextEditingController(text: str);
      textEditingControllers.add(textEditingController);
    });
  }

  @override
  void dispose() {
    super.dispose();
    // dispose textEditingControllers to prevent memory leaks
    for (TextEditingController textEditingController in textEditingControllers) {
      textEditingController?.dispose();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('title'),
      ),
      body: ListView.builder(
        itemCount: stringListReturnedFromApiCall.length,
        itemBuilder: (BuildContext context, int index) {
          return Padding(
            padding: const EdgeInsets.all(10.0),
            child: TextField(
              controller: textEditingControllers[index],
            ),
          );
        },
      ),
    );
  }
}

答案 4 :(得分:0)

包含您的控制器的列表

if (lines.error) return "Failed to load resource Machine Status";
  if (lines.status === "success") {
    for (let i = 0; i < lines.data.length; i++) {
      options.lines[i] = {
        value: lines.data[i].line_number,
        label: lines.data[i].line_number,
      };
    }
  }

为了填充 myControllers 而调用的函数

<块引用>
     var myControllers = []; 
        

在你的 statefullwidget 中初始化 createKeys 像这样使用它,例如在列表视图构建器中;

<块引用>
          createControllers() {
            myControllers = [];
            for (var i = 0; i < your_items.length; i++) {
              myControllers.add(TextEditingController());
            }
          }