Search code examples
flutterdartflutter-provider

Is there an alternative to notifyListeners


Is There another method that can substitutes notifyListeners?

I have to update the provider but with another way.


Solution

  • I can provide two ways of doing this. For example in this case Im changing a text field with some help of Provider:

    1. Value Notifier + Provider

    Provider class TextProvider

    class TextProvider extends ChangeNotifier {
      final ValueNotifier<String> _textNotifier = ValueNotifier<String>('');
      ValueNotifier<String> get text => _textNotifier;
    
      void setText(String text) => _textNotifier.value = text;
    }
    

    Anywhere below the Provider context:

    Column(
              children: [
                TextField(
                  onChanged: (value) {
                    Provider.of<TextProvider>(context, listen: false)
                        .setText(value);
                  },
                ),
                SizedBox(
                  height: 20,
                ),
                ValueListenableBuilder<String>(
                  valueListenable:
                      Provider.of<TextProvider>(context, listen: false).text,
                  builder: (context, value, _) => Text(
                    '$value',
                    style: Theme.of(context).textTheme.headline4,
                  ),
                ),
              ],
    

    2. Function Callbacks + Provider

    Provider class TextProvider

    typedef TextCallback = void Function(String text);
    
    class TextProvider extends ChangeNotifier {
      final _textListener = ObserverList<TextCallback>();
    
      void textListener(TextCallback callback) => _textListener.add(callback);
    
      void _notifyTextChanged(String text) {
        for (final listener in _textListener) {
          listener.call(text);
        }
    
       //notifyListeners(); //Can call if you want to notify other listeners
      }
    
      void triggerTextChange(String text) => _notifyTextChanged(text);
    }
    
    

    Anywhere below the Provider context:

    ...
    
    class _MyHomePageState extends State<MyHomePage> {
      late final TextProvider provider;
      String? text;
    
      @override
      void initState() {
        super.initState();
        provider = Provider.of<TextProvider>(context, listen: false);
    
        provider.textListener((String s) {
          setState(() {
            text = s;
          });
        });
      }
    
    ...
    
    @override
    Widget build(BuildContext context) {
    ...
    
     child: Column(
              children: [
                TextField(
                  onChanged: (value) {
                    provider.triggerTextChange(value);
                  },
                ),
                SizedBox(
                  height: 20,
                ),
                Text(
                  '$text',
                  style: Theme.of(context).textTheme.headline4,
                ),
              ],
            ),
    
    ...
    
    }