Reputation: 489
DBHelper dbHelper = DBHelper();
List<Map<String, dynamic>> lists;
@override
Widget build(BuildContext context) {
return FutureBuilder<List<Map<String, dynamic>>>(
future: dbHelper.selectMemo(userkey, 1),
builder: (context, snapshot){
if(snapshot.hasData){
if(snapshot.data.length != 0){
lists = List<Map<String, dynamic>>.from(snapshot.data);
return ListView.separated(
separatorBuilder: (context, index){
return Divider(
thickness: 0,
);
},
itemCount: lists.length,
itemBuilder: (context, index){
return ListTile(
title: Text(lists[index]["memo"]),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: (){
setState(() {
lists = List.from(lists)..removeAt(index);
});
},
),
);
},
);
}
}
},
);
}
This is my code. My lists come from sqlflite. And I want to delete my item from Listview. But this code doesn't work. I don't know where I made the mistake.
Upvotes: 0
Views: 409
Reputation: 111
This behavior is normal. If you print some logs in the build statement, you will find that every time you click the delete button (setState), Widget will build again.
In addition, lists are re-assigned to DB data after each build
lists = List<Map<String, dynamic>>.from(snapshot.data);
So, it looks like the delete operation is not working.
This phenomenon if you've seen Flutter setState part of the source code will be well understood.
In setState, the callback is performed first, and then mark dirty
void setState(VoidCallback fn) {
final dynamic result = fn() as dynamic;
_element.markNeedsBuild();
}
So, there are two ways to solve this problem:
(1) Do not directly change the value of lists, but when the delete button is pressed, to delete the data in the database, so that when Widget build again, the data taken out of the database is correct.
(2) Add a flag to judge whether the data is initialized, and then add a judgment before assigning lists. If the data is initialized, assignment operation will not be carried out
I hope it worked for you. ^-^
Upvotes: 1