Issue
At start, I load data from the database that populates the ListView. These data is displayed on the ListView title and subtitle. When a user taps on one of the items on the list, a showModalBottomSheet popups with fields to update the list(index). This update is carried out successfully but on the close of the showModalBottomSheet, the values on each ListView item refreshes to default (data from database).
Please, how can I update the ListView items without the ListView refreshing to initial data value?
Widget _buildSubjects(BuildContext context, int index) {
response = getFieldData(_snapshot!.data[index]);
return ListTile(
trailing: IconButton(
icon: Icon(Icons.add),
onPressed: () {
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) {
return SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: Text(
_snapshot!.data[index]['name']
.toString()
.toUpperCase(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
),
),
Form(
key: _scoreForm,
child: Column(
children: [
scoreFields(_snapshot!.data[index]),
SizedBox(
height: 10.0,
),
ElevatedButton(
onPressed: () {
if (!_scoreForm.currentState!.validate())
return;
_scoreForm.currentState!.save();
setState(() {
response = "New Value";
});
//close bottomsheet
Navigator.pop(context);
},
child: Text("Save Score"),
),
],
),
),
],
),
),
);
},
);
},
),
title: Text(
_snapshot!.data[index]['name'].toString().toUpperCase(),
style: TextStyle(
fontWeight: FontWeight.w400,
),
),
subtitle: Text(
response,
),
onTap: () {},
);
}
Solution
You may wrap your ListTile with ValueListenableBuilder like below:
ValueNotifier<bool> newData = ValueNotifier(false);
ValueListenableBuilder<bool>(
valueListenable: newData,
builder: (context, value, child) {
return ListTile(
trailing: IconButton(
icon: Icon(Icons.add), //... rest of your code
and instead of calling
setState(() {
response = "New Value";
});
call below without setState
response = "New Value";
newData.value = !newData.value;
so now the state of the ListTile will be updated and no need to setState for the complete listview.
Answered By - ammar
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.