How to solve: Update the SubTitle of a listview without refreshing in Flutter

Question

Asked by BlackPearl on December 31, 2021 (source).

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: () {},
);
}

Answer

Question answered by ammar (source).

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.

Video Answers on YouTube

ANDROID DART FLUTTER LISTVIEW
SHARE: