我正在重新创建我之前在Swift中创建的应用程序,在我的一个页面上,我们称之为API,并根据结果,向用户显示动态数量的文本字段,以便按不同的搜索参数进行搜索。
在Dart / Flutter中有什么好办法吗?由于dart不支持在运行时生成代码,这是否可能?
答案 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());
}
}