如果我删除或添加项目,我想更新我的ListView.现在我只想删除项目,并立即查看项目的删除情况.
我的应用程序比较复杂,所以我编写了一个小示例项目来说明我的问题.
TestItem
类包含一些数据条目:
class TestItem {
static int id = 1;
bool isFinished = false;
String text;
TestItem() {
text = "Item ${id++}";
}
}
ItemInfoViewWidget
是TestItem
的UI表示,如果完成则删除该项(只要复选框更改为true).
class ItemInfoViewWidget extends StatefulWidget {
TestItem item;
List<TestItem> items;
ItemInfoViewWidget(this.items, this.item);
@override
_ItemInfoViewWidgetState createState() =>
_ItemInfoViewWidgetState(this.items, this.item);
}
class _ItemInfoViewWidgetState extends State<ItemInfoViewWidget> {
TestItem item;
List<TestItem> items;
_ItemInfoViewWidgetState(this.items, this.item);
@override
Widget build(BuildContext context) {
return new Card(
child: new Column(
children: <Widget>[
new Text(this.item.text),
new Checkbox(
value: this.item.isFinished, onChanged: isFinishedChanged)
],
),
);
}
void isFinishedChanged(bool value) {
setState(() {
this.item.isFinished = value;
this.items.remove(this.item);
});
}
}
ItemViewWidget
级建造了ListView
.
class ItemViewWidget extends StatefulWidget {
List<TestItem> items;
ItemViewWidget(this.items);
@override
_ItemViewWidgetState createState() => _ItemViewWidgetState(this.items);
}
class _ItemViewWidgetState extends State<ItemViewWidget> {
List<TestItem> items;
_ItemViewWidgetState(this.items);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: new Text('Test'),
),
body: ListView.builder(
itemCount: this.items.length,
itemBuilder: (BuildContext context, int index) {
return new ItemInfoViewWidget(this.items, this.items[index]);
}),
);
}
}
MyApp
显示了一个TestItem
和一个导航到ItemViewWidget
页的按钮.
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
List<TestItem> items = new List<TestItem>();
_MyHomePageState() {
for (int i = 0; i < 20; i++) {
this.items.add(new TestItem());
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Column(
children: <Widget>[
ItemInfoViewWidget(this.items, this.items.first),
FlatButton(
child: new Text('Open Detailed View'),
onPressed: buttonClicked,
)
],
));
}
void buttonClicked() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ItemViewWidget(this.items)),
);
}
}
如果我切换第一个项目的复选框,该复选框将标记为已完成(如预期的那样),但它不会从UI中删除,但会从列表中删除.
然后我回到主页,我可以看到第1项也被选中了.
因此,如果我再次转到ItemViewWidget
页,我可以观察到选中的项目不再存在.
基于这些观察,我得出结论,我的实现可以工作,但是我的UI没有更新.
如何更改代码才能立即更新UI?
Edit: This is not a duplicate, because
- 我不想仅仅为了更新UI而创建我的列表的新实例.
- 答案不起作用:我添加了
this.items = List.from(this.items);
个,但我的应用程序的行为与上面描述的相同. - 我不想通过调用
List.from
来打破我的引用链,因为我的体系 struct 有一个被几个类引用的列表.如果我打破了链条,我必须自己更新所有的引用.我的架构有问题吗?