如何解决Flutter web,Consumer 重建后的奇怪结果
我有一个颤动的表单,其中包含一个带有 textFormFields 行的列。 每行末尾都有一个图标按钮,用于删除所述行。这些行是用消费者构建的。
我有一个通知程序类,其中包含消费者监听的数据。
当按下删除按钮时,通知程序类中的一个函数被调用,负责删除具有给定索引的行。相同的功能是打印出删除前和删除后的数据集。打印效果不错,效果符合预期。
Consumer 还重建了少一行的数据集。但是在 ui 中呈现的数据并不像预期的那样。
在负责构建行的小部件中,我打印出放在 textFormField 的 initialValue 中的数据。印刷品看起来不错,再次符合预期。但是 ui 不会呈现打印显示的内容。 查看图片和代码。
准备删除第二行:
删除后:
删除行并打印数据的代码。
void deletePoint({int switchpointIndex,int pointIndex,Point point}) {
for (Switchpoint switchpoint in _settings.switchpoints) {
for (Point point in switchpoint.points) {
print("Tag: ${point.tag}. And Type: ${point.type}");
}
}
_settings.switchpoints[switchpointIndex].points.removeAt(pointIndex);
for (Switchpoint switchpoint in _settings.switchpoints) {
for (Point point in switchpoint.points) {
print("Tag: ${point.tag}. And Type: ${point.type}");
}
}
notifyListeners();
}
打印结果(如预期):
标签:并输入:a
标签:b。并输入:b
标签:c。并输入:c
标签:并输入:a
标签:c。并输入:c
打印和呈现行 Widget 中数据的代码:
@override
Widget build(BuildContext context) {
print("PointIndex: $pointIndex,value: ${point.tag} and ${point.type}");
return Row(
...
TextFormField(
...
initialValue: point.tag ?? ''
...
TextFormField(
...
initialValue: point.type ?? ''
...
这也会打印预期的内容:
PointIndex: 0,value: a and a
PointIndex:1,值:c 和 c
有人知道发生了什么吗?
-- 编辑 --
没有 TextEditingController。
表格代码:
return Container(
padding: EdgeInsets.symmetric(horizontal: 10),child: Form(
key: _formKey,child: Column(
crossAxisAlignment: CrossAxisAlignment.start,children: [
SizedBox(
height: 50,),Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [
Text(
'Switchpoint Layout',style: TextStyle(
color: Colors.teal,fontSize: 20,fontWeight: FontWeight.bold),TextButton.icon(
onPressed: () {
context
.read<SettingsNotifier>()
.addEmptySwitchpoint();
},icon: Icon(Icons.add),label: Text('Add Switchpoint')),],Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),child: Consumer<SettingsNotifier>(
builder: (context,notifier,child) {
List<SwitchpointRow> switchpointRows = [];
int switchpointIndex = 0;
for (Switchpoint switchpoint
in notifier.switchPoints) {
switchpointRows.add(SwitchpointRow(
switchpoint: switchpoint,switchpointIndex: switchpointIndex,formKey: _formKey,));
switchpointIndex++;
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,children: switchpointRows),);
}),Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),child: ElevatedButton(
onPressed: () async {
print(context
.read<SettingsNotifier>()
.settings
.toJson());
if (_formKey.currentState.validate()) {}
},child: Text('Submit'),);
SwitchpointRow 代码:
class SwitchpointRow extends StatelessWidget {
const SwitchpointRow({
Key key,@required this.switchpoint,@required this.switchpointIndex,@required this.formKey,}) : super(key: key);
final int switchpointIndex;
final Switchpoint switchpoint;
final formKey;
List<PointRow> loadPoints(List<Point> points) {
List<PointRow> pointRows = [];
int pointIndex = 0;
for (Point point in points) {
pointRows.add(PointRow(
point: point,pointIndex: pointIndex,last: points.last == point ? true : false));
pointIndex++;
}
return pointRows;
}
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.only(bottom: 20),child: Column(
mainAxisSize: MainAxisSize.min,children: [
AppBar(
backgroundColor: Colors.amberAccent,title: TextFormField(
decoration: InputDecoration(
border: InputBorder.none,contentPadding: EdgeInsets.fromLTRB(0,2,4),isDense: true,hintText: 'Switchpoint name',labelText: 'Switchpoint name',initialValue: switchpoint.name ?? '',onChanged: (value) {
context
.read<SettingsNotifier>()
.switchPoints[switchpointIndex]
.name = value;
},validator: (value) {
if (value.isEmpty) {
return 'mandatory';
}
return null;
}),actions: [
Padding(
padding: const EdgeInsets.only(right: 18.0),child: TextButton.icon(
onPressed: () {
context.read<SettingsNotifier>().deleteSwitchpoint(
switchpointIndex: switchpointIndex);
},icon: Icon(Icons.delete),label: Text('Delete Switchpoint'),Padding(
padding: const EdgeInsets.only(right: 8.0),child: TextButton.icon(
onPressed: () {
context
.read<SettingsNotifier>()
.addPoint(switchpointIndex);
},label: Text('Point'),Padding(
padding: const EdgeInsets.only(left: 50.0),child: Column(children: loadPoints(switchpoint.points)),);
}
}
PointRow 代码:
class PointRow extends StatelessWidget {
const PointRow(
{Key key,@required this.point,@required this.pointIndex,@required this.last})
: super(key: key);
final Point point;
final int pointIndex;
final int switchpointIndex;
final bool last;
@override
Widget build(BuildContext context) {
print("PointIndex: $pointIndex,value: ${point.tag} and ${point.type}");
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [
Expanded(
flex: 3,child: TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(0,hintText: 'Tag',labelText: 'Point tag',onChanged: (value) {
context
.read<SettingsNotifier>()
.switchPoints[switchpointIndex]
.points[pointIndex]
.tag = value;
},initialValue: point.tag ?? '',validator: (value) {
if (value.isEmpty) {
return 'mandatory';
}
return null;
}),SizedBox(width: 30.0),Expanded(
flex: 3,child: TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(0,hintText: 'Type',labelText: 'Type of point',onChanged: (value) {
context
.read<SettingsNotifier>()
.switchPoints[switchpointIndex]
.points[pointIndex]
.type = value;
},initialValue: point.type ?? '',Expanded(
child: IconButton(
padding: EdgeInsets.all(0.0),onPressed: () {
context.read<SettingsNotifier>().deletePoint(
switchpointIndex: switchpointIndex,point: point);
},)
],);
}
}
解决方法
因此,经过反复试验,解决方案必须是 TextEditingController,我想避免使用它,因为最终会有几个字段。
所以解决方案是一个像这样的内联控制器:
TextFormField(
...
controller: TextEditingController()..text = 'the value',...
);
这样,用户界面就会按照我的意愿行事。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。