I have created a ListView.builder of custom Widgets based on entries in a database. Now I am trying to add a delete function. When I click on the button, the entry gets removed from the database accordingly. However, the ListView does not update despite setState() being called. I suspect that this might be due to the delete method being async, how can I have the app first delete the entry and then refresh the ListView?
The code for my ListView.builder is:
ListView.builder(
padding: const EdgeInsets.all(8.0),
itemExtent: 106.0,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return CustomListItem(
name: transactionsReversed[index].name,
category: transactionsReversed[index].category,
sign: transactionsReversed[index].sign,
amount: transactionsReversed[index].amount,
id: transactionsReversed[index].id,
delete: (){
print('Running delete function on ${transactionsReversed[index].id}');
setState(() {
_remove(transactionsReversed[index].id);
});
}
);
}
),
The custom list item looks like this:
class CustomListItem extends StatelessWidget {
const CustomListItem({
this.name, this.category, this.sign, this.amount, this.id, this.delete
});
final String name;
final String category;
final String sign;
final double amount;
final int id;
final Function delete;
@override
Widget build(BuildContext context) {
const double radius = 15.0;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0),
child: InkWell(
onTap: () {
Navigator.pushNamed(context, '/category_viewer', arguments: {
'category': category
});
},
child: Container(
color: Colors.transparent,
child: Container(
decoration: BoxDecoration(
color: Colors.black,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(radius),
topRight: const Radius.circular(radius),
bottomLeft: const Radius.circular(radius),
bottomRight: const Radius.circular(radius),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 1,
child: IconButton(
onPressed: delete,
icon: Icon(
Icons.delete_outlined,
color: Colors.red,
size: 40,
),
color: Colors.red
),
),
Expanded(
flex: 3,
child: Padding(
padding: const EdgeInsets.fromLTRB(5.0, 0.0, 0.0, 0.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
name,
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 20.0,
color: Colors.white
),
),
const Padding(padding: EdgeInsets.symmetric(vertical: 2.0)),
Text(
category,
style: const TextStyle(
fontSize: 14.0,
color: Colors.white
),
),
],
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 50, 0),
child: Text(
'$sign${amount.toStringAsFixed(2)}€',
style: TextStyle(
fontSize: 25.0,
color: sign == '+' ? Colors.green : Colors.red
),
),
),
],
),
),
),
),
);
}
}
Finally, the remove method is simply:
_remove(int id) async {
DatabaseHelper helper = DatabaseHelper.instance;
await helper.deleteTransaction(id);
}