在 Flutter 中使用 TextFormField 添加项目列表
Adding list of items using TextFormField in Flutter
我正在尝试实现添加电子邮件列表而不是用户输入的功能。这是我目前所拥有的
List<String> _notificationEmails =[];
var _notificationEmailsController = TextEditingController();
Widget _buildNotificationEmailsInput() {
return TextFormField(
controller: _notificationEmailsController,
style: inputTextStyle,
maxLines: null,
validator: (String value) {
print(value);
if (value.isEmpty) {
return 'Emails Required';
}
return null;
},
onChanged: (String value){
if(value.substring(value.length-1)==','){
print('here');
setState(() {
_notificationEmails.add(value.substring(0,value.length-1));
});
_notificationEmailsController.clear();
}
print(_notificationEmails);
},
);
}
我的预期结果是,当用户输入一封电子邮件然后在其后添加一个逗号时,该电子邮件将附加到列表中并清除输入字段,但我得到了导致此操作的循环 _notificationEmails.add(value.substring(0,value.length-1));
运行无穷大。
这是日志
[ +3 ms] flutter: [je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gm<…>
这种情况一直持续下去。我做错了什么?
更新
如果有帮助,我已经意识到问题是因为每次调用 _notificationEmailsController.clear();
时都会触发 onChange()
从而导致循环。
更新:请在 Future.delayed
内调用 TextEditingController.clear
。因为根据 clear
...
的描述
this method should only be called between frames, e.g. in response to
user actions, not during the build, layout, or paint phases.
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyApp createState() => _MyApp();
}
class _MyApp extends State<MyApp> {
final List<String> _notificationEmails = <String>[];
final TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
_buildNotificationEmailsInput(),
Expanded(
child: ListView.builder(
itemCount: _notificationEmails.length,
itemBuilder: (_, int idx) => ListTile(
title: Text(_notificationEmails[idx]),
),
),
),
],
),
),
);
}
Widget _buildNotificationEmailsInput() {
return TextFormField(
controller: _controller,
validator: (String value) {
print('VALIDATOR: $value');
if (value.isEmpty) {
return 'Emails Required';
}
return null;
},
onChanged: (String value) {
if (value.substring(value.length - 1) == ',') {
print('>>>>>> value = $value : controller = ${_controller.hashCode}');
setState(() {
_notificationEmails.add(value.substring(0, value.length - 1));
});
Future<void>.delayed(
const Duration(milliseconds: 10),
_controller.clear,
);
print(_notificationEmails);
}
},
);
}
}
**You have to add a list of *TextEditingController* and need to add the contoller text to that list and parse it as you need.**
List<String> selection = [];
List<Product> productList = [];
//---------Adding contoller to list
productProvider.getAll(user.guid).forEach((element) {//---List<Product>
final TextEditingController quantityController =
TextEditingController(text: element.quantity);
quantityControllers.add(quantityController);
});
//-------Adding list of products to list
List<Map<String, dynamic>> productItems = [];
List<Product> productOriginalList =
productProvider.getAll(user.guid);
for (int i = 0; i < productOriginalList.length; i++) {
final Product product = productOriginalList[i];
if (selection.contains(product.equipmentId)) {
productItems.add(product.toJson(quantityControllers[i].text));
}
/* Map<String, dynamic> toJson(String quan) => {
'ProductId': id,
'Quantity': quan,
};
TextField(
controller: quantityControllers[index],*/
我正在尝试实现添加电子邮件列表而不是用户输入的功能。这是我目前所拥有的
List<String> _notificationEmails =[];
var _notificationEmailsController = TextEditingController();
Widget _buildNotificationEmailsInput() {
return TextFormField(
controller: _notificationEmailsController,
style: inputTextStyle,
maxLines: null,
validator: (String value) {
print(value);
if (value.isEmpty) {
return 'Emails Required';
}
return null;
},
onChanged: (String value){
if(value.substring(value.length-1)==','){
print('here');
setState(() {
_notificationEmails.add(value.substring(0,value.length-1));
});
_notificationEmailsController.clear();
}
print(_notificationEmails);
},
);
}
我的预期结果是,当用户输入一封电子邮件然后在其后添加一个逗号时,该电子邮件将附加到列表中并清除输入字段,但我得到了导致此操作的循环 _notificationEmails.add(value.substring(0,value.length-1));
运行无穷大。
这是日志
[ +3 ms] flutter: [je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gmail.com, je@gm<…>
这种情况一直持续下去。我做错了什么?
更新
如果有帮助,我已经意识到问题是因为每次调用 _notificationEmailsController.clear();
时都会触发 onChange()
从而导致循环。
更新:请在 Future.delayed
内调用 TextEditingController.clear
。因为根据 clear
...
this method should only be called between frames, e.g. in response to user actions, not during the build, layout, or paint phases.
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyApp createState() => _MyApp();
}
class _MyApp extends State<MyApp> {
final List<String> _notificationEmails = <String>[];
final TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
_buildNotificationEmailsInput(),
Expanded(
child: ListView.builder(
itemCount: _notificationEmails.length,
itemBuilder: (_, int idx) => ListTile(
title: Text(_notificationEmails[idx]),
),
),
),
],
),
),
);
}
Widget _buildNotificationEmailsInput() {
return TextFormField(
controller: _controller,
validator: (String value) {
print('VALIDATOR: $value');
if (value.isEmpty) {
return 'Emails Required';
}
return null;
},
onChanged: (String value) {
if (value.substring(value.length - 1) == ',') {
print('>>>>>> value = $value : controller = ${_controller.hashCode}');
setState(() {
_notificationEmails.add(value.substring(0, value.length - 1));
});
Future<void>.delayed(
const Duration(milliseconds: 10),
_controller.clear,
);
print(_notificationEmails);
}
},
);
}
}
**You have to add a list of *TextEditingController* and need to add the contoller text to that list and parse it as you need.**
List<String> selection = [];
List<Product> productList = [];
//---------Adding contoller to list
productProvider.getAll(user.guid).forEach((element) {//---List<Product>
final TextEditingController quantityController =
TextEditingController(text: element.quantity);
quantityControllers.add(quantityController);
});
//-------Adding list of products to list
List<Map<String, dynamic>> productItems = [];
List<Product> productOriginalList =
productProvider.getAll(user.guid);
for (int i = 0; i < productOriginalList.length; i++) {
final Product product = productOriginalList[i];
if (selection.contains(product.equipmentId)) {
productItems.add(product.toJson(quantityControllers[i].text));
}
/* Map<String, dynamic> toJson(String quan) => {
'ProductId': id,
'Quantity': quan,
};
TextField(
controller: quantityControllers[index],*/