Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Provider - Selector not updating UI for list items

Tags:

flutter

I have a ListView consists of several ListTiles which have a trailing icon. The color of icon should change from transparent to green based on user tap. However the UI is not updating on user interaction.

The ServiceModel is like this.

class ProviderService extends ChangeNotifier {
  final List<String> totalNames = ['Somesh', 'Tarulata', 'Indranil', 'Satyajyoti', 'Biswas', 'Sajal', 'Kumar', 'Jhuma', 'Mondal'];

  List<String> _selectedNames = [];
  List<String> get selectedNames => _selectedNames;

  void updateselectedNames(String name) {
    bool isExists = _selectedNames.contains(name);

    if (isExists)
      _selectedNames.remove(name);
    else
      _selectedNames.add(name);

    notifyListeners();
  }
}

The ListView goes like this.

class Members extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ProviderService plService = Provider.of<ProviderService>(context, listen: false);

    return Scaffold(
      body: SafeArea(
        child: Selector<ProviderService, List<String>>(
          selector: (_, service) => service.selectedNames,
          builder: (context, selNames, child) {
            if (plService.totalNames.isEmpty) return child;

            return ListView.separated(
              shrinkWrap: true,
              itemBuilder: (context, index) {
                String _name = plService.totalNames[index];

                return ListTile(
                  title: Text('$_name'),
                  trailing: Icon(
                    Icons.check_circle,
                    color: selNames.contains(_name) ? Colors.lightGreen : Colors.transparent,
                  ),
                  onTap: () {
                    plService.updateselectedNames(_name),
                    print(selNames);
                  },
                );
              },
              separatorBuilder: (_, __) => Divider(),
              itemCount: plService.totalNames.length,
            );
          },
          child: Center(
            child: Text('No names have been found', textAlign: TextAlign.center),
          ),
        ),
      ),
    );
  }
}

and of course the main.dart is like this.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ChangeNotifierProvider(
        create: (context) => ProviderService(),
        child: Members(),
      ),
    );
  }
}

Even though the list selectedNames updated, the UI remains same. What's going on wrong here ?

like image 207
Satyajyoti Biswas Avatar asked Oct 23 '25 14:10

Satyajyoti Biswas


1 Answers

You may add the shouldRebuild parameter of Selector and return true。like this:

Selector<ProviderService, List<String>>(
          selector: (_, service) => service.selectedNames,
          builder: (context, selNames, child) {...},
          shouldRebuild: (previous, next) => true,
       )
like image 146
user16054919 Avatar answered Oct 26 '25 05:10

user16054919