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: () {},
);
}
CodePudding user response:
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.
CodePudding user response:
To update the data in Listtile(title and subtitle) you need to use Stream and Streambuilder which will update the data based on stream change from your database.