I have a ListView
containing 5 elements in the following order:
- Section Header
- Valid Item 0
- Valid Item 1
- Section Header
- Invalid Item 0
When I swipe to delete Valid Item 0
, the ListView
length becomes 4 instead of 5 (as expected), the UI appears in the order below, with only 3 items. I have also determined that each element in the ListView.builder
, is being returned correctly (in the order above, except for Valid Item 0
, as expected). Each Widget is being build as expected.
- Section Header
- Section Header
- Invalid Item 0
The UI appears correctly until I call setState(() {})
. Once it is called, Valid Item 1
is removed from the UI, but not the data source. If I switch the current display to a different Scaffold
(as shown in the video below), then switch back, the UI shows correctly again. Strange.
CodePudding user response:
I ended up figuring it out myself after several hours of trial and error.
The key component here is literally key
. I didn't realize the purpose of the key initially. It seems to be used to coordinate which cell is being deleted on the UI with its corresponding data. The key
for each SwipeActionCell
should reference the exact same data child which will be deleted.
SwipeActionCell(
key: ObjectKey(data["valid"]![privateIndex]),
...
)
where privateIndex
is the index for the list item in that section, ignoring any section headers and previous sections. Eg:
1. Section Header listIndex: 0 privateIndex: N/A
2. Valid Item 0 listIndex: 1 privateIndex: 0
3. Valid Item 1 listIndex: 2 privateIndex: 1
4. Section Header listIndex: 3 privateIndex: N/A
5. Invalid Item 0 listIndex: 4 privateIndex: 0
and where data
is:
Map<String,List<dynamic>> data = {
"valid": [
{"title":"Valid Item 0"},
{"title":"Valid Item 1"}
],
"invalid": [
{"title":"Invalid Item 0"}
]
}