flutter - Flutter:从列表中删除元素不会删除循环生成的相应UI元素
问题描述
我有一个 DataTable,我在其中将带有 for 循环的 DataRows 添加到 UI。循环遍历列表。在 UI 上,可以在列表中添加和删除项目。
如图所示,每个 DataRow 都有 TextFormFields 以获取一些输入。这是我的问题:当我在行的 TextFields 中放入一些值然后删除其中一个行时,尽管我更改了 List 中的值并相应地更新了状态,但最后一行总是被删除。
带有 TextFormFields 的 DataTableRows
因此,例如,如果我尝试删除图片中权重设置为 10 的第一行,则在最后一行消失后,第一行中的值 10 仍然存在。由于我在删除行时更新了状态,并且输入都将它们的 initialValues 设置为与列表中的值相对应,所以 10 的行不应该消失吗?还是我的思维过程有问题?打印语句显示正确的 ListItem 被删除,所以我不太确定这里发生了什么。
我对 Flutter 和 Dart 真的很陌生,所以非常感谢任何帮助!
这里是表的代码:
import "package:flutter/material.dart";
import 'package:pr_note_app/definitions/ExerciseSet.dart';
class ExerciseTable extends StatefulWidget {
final String name;
ExerciseTable({Key key, @required this.name}) : super(key: key);
@override
_ExerciseTableState createState() => _ExerciseTableState();
}
class _ExerciseTableState extends State<ExerciseTable> {
var _sets = [new ExerciseSet("-", "", "")];
void popUpMenuButtonItemSelected(value) {
switch (value) {
case "Add Set":
setState(() {
_sets.add(new ExerciseSet("-", "", ""));
});
break;
default:
}
}
void removeSetAt(index) {
print(_sets);
setState(() {
_sets.removeAt(index);
});
print(_sets);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
AppBar(
elevation: 0,
title: TextFormField(
initialValue: widget.name,
cursorColor: Colors.black,
decoration: new InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
hintText: "My New Exercise"),
),
actions: [
PopupMenuButton(
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
const PopupMenuItem(value: "Add Set", child: Text("Add Set")),
const PopupMenuItem(
value: "Remove Exercise", child: Text("Remove Exercise"))
],
onSelected: (value) => popUpMenuButtonItemSelected(value),
),
],
iconTheme: IconThemeData(color: Colors.black),
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
),
// SET NUMBER | LAST | WEIGHT | REPS
DataTable(
showCheckboxColumn: false,
columnSpacing: 30,
columns: const <DataColumn>[
DataColumn(
label: Text(
'Set',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Last',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Weight',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Reps',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(label: Text(""))
],
rows: [
for (var i = 0; i < _sets.length; i++)
DataRow(onSelectChanged: (bool) => print("select $bool"), cells: [
// SET NUMBER
DataCell(Text("${i + 1}")),
// LAST
DataCell(Text("${_sets[i].last}")),
// WEIGHT
DataCell(Container(
width: MediaQuery.of(context).size.width * 0.13,
child: TextFormField(
initialValue: "${_sets[i].weight}",
onChanged: (value) {
setState(() {
_sets[i].weight = value;
});
},
cursorColor: Colors.black,
decoration: new InputDecoration(
isDense: true,
fillColor: Colors.grey[200],
filled: true,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
)))),
// REPS
DataCell(Container(
width: MediaQuery.of(context).size.width * 0.13,
child: TextFormField(
initialValue: "${_sets[i].reps}",
onChanged: (value) {
setState(() {
_sets[i].reps = value;
});
},
cursorColor: Colors.black,
decoration: new InputDecoration(
isDense: true,
fillColor: Colors.grey[200],
filled: true,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
)))),
DataCell(Container(
width: MediaQuery.of(context).size.width * 0.13,
child: IconButton(
icon: Icon(Icons.delete),
onPressed: () => removeSetAt(i),
color: Colors.black,
),
))
])
],
)
],
crossAxisAlignment: CrossAxisAlignment.stretch,
);
}
}
解决方案
原因可能是框架无法确定分配给项目的状态。您需要将密钥添加到DataRow
:
DataKey(
key: ObjectKey(_sets[i]),
...
推荐阅读
- node.js - TypeError:params 不是 dockerized 应用程序中的函数
- reactjs - 如何将图像作为背景放置在 React 应用程序中?
- javascript - JavaScript如何用字符串中的换行符替换点
- python - 标签文本不会在 python tkinter 上立即更改
- javascript - webpack 插件中的“应用”是否与 js 中的“应用”相同,这意味着更改它
- reactjs - 检查文件是图像还是视频,并使用正确的标签?
- c++ - 使用 v4l2 在 C++ 中捕获 YUYV
- python - 获取所有指定大小的连续子序列,同时也环绕到前面
- c++ - 使用类和运算符重载计算 3D 中两点之间距离的程序
- java - SpringBoot - 从第一个模块welcomeController 返回第二个模块的html页面