问题
I am recreating an app I have previously made in Swift, and on one of my pages we call an API and based on the results, we present the user a dynamic number of textfields to search by different search parameters.
Is there any good way to do this in Dart/Flutter? Since dart doesn't support generating code at runtime, is this even a possibility?
回答1:
I just modified @Felix's answer with using Map to store TextEditingControllers instead of list. I think its easy to call textEditingControllers with key value pairs. Modified code block;
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);
});
})
]
)));
}
}
when you write something to textfields and hit to print button results ;
flutter: first controller text
flutter: second controller text
flutter: third controller text
flutter: fourth controller text
flutter: so on .......
回答2:
More or less as @Günter Zöchbauer mentioned, you can just build a list of widgets which are nested then in a container.
Here's a simple example:
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,
)));
}
}
Edit: Added list for TextEditingController
s to interact with all the TextField
s
来源:https://stackoverflow.com/questions/50766139/flutter-create-dynamic-number-of-texteditingcontrollers