Это была проблема.
у обновить свой ListView, если я удаляю или добавляю элементы. Сейчас я просто хочу удалить элементы и сразу же увидеть их удаление.
Мое приложение более сложное, поэтому я написал небольшой пример проекта, чтобы показать свои проблемы.
TestItem
класс содержит несколько записей данных:
class TestItem {
static int id = 1;
bool isFinished = false;
String text;
TestItem() {
text = "Item ${id++}";
}
}
ItemInfoViewWidget
является интерфейсом представленияTestItem
и удаляет элемент, если он завершен (всякий раз, когда флажок изменяется на 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)),
);
}
}
Если я переключаю флажок первого элемента, флажок помечается как завершенный (как и ожидалось), но он не удаляется из пользовательского интерфейса - однако он удаляется из списка.
Затем я возвращаюсь на главную страницу и вижу, что там также проверен пункт 1.
Так что, если я пойду кItemViewWidget
снова, я могу заметить, что проверенных пунктов больше нет. Основываясь на этих наблюдениях, я прихожу к выводу, что моя реализация работает, но мой интерфейс не обновляется.
Как я могу изменить свой код, чтобы сделать возможным немедленное обновление пользовательского интерфейса?
Изменить: это не дубликат, потому что
Я не хочу создавать новый экземпляр моего списка только для обновления пользовательского интерфейса.Ответ не работает: я добавилthis.items = List.from(this.items);
но поведение моего приложения такое же, как описано выше.Я не хочу разрывать мою цепочку ссылок, звоняList.from
потому что моя архитектура имеет один список, на который ссылаются несколько классов. Если я разорву цепь, мне придется обновить все ссылки самостоятельно. Есть ли проблема с моей архитектурой?