flutterflutter-state

Is there a way to make a `ChangeNotifier` listen to another `ChangeNotifier` in a flutter app?


Is there a way to make a ChangeNotifier listen to another ChangeNotifier in a flutter app?

something like this:

class FirstCounter extends ChangeNotifier {
    int _i = 0;
    void increment() {
        i = i + 1;
        notifyListeners();
    }
}

class SecoundCounter extends ChangeNotifier {
    int _i = 0;
    void increment() {
        i = i + 1;
        notifyListeners();
    }

    void listen() {
        var resetCallback = () { i = 0;}
        FirstCounter.listen(resetCallback);
    }
}

I want SecoundCounter to reset when FirstCounter is updated.


Solution

  • use first.addListener(second.reset);

    import 'package:flutter/material.dart';
    
    class FirstCounter extends ChangeNotifier {
      int i = 0;
      void increment() {
        i = i + 1;
        notifyListeners();
      }
    }
    
    class SecondCounter extends ChangeNotifier {
      int i = 0;
    
      void increment() {
        i = i + 1;
        notifyListeners();
      }
    
      void reset() {
        i = 0;
        notifyListeners();
      }
    }
    
    class CounterWidget extends StatefulWidget {
      const CounterWidget({super.key});
    
      @override
      State<CounterWidget> createState() => _CounterWidgetState();
    }
    
    class _CounterWidgetState extends State<CounterWidget> {
      final FirstCounter first = FirstCounter();
      final SecondCounter second = SecondCounter();
      @override
      void initState() {
        super.initState();
        first.addListener(second.reset);
      }
    
      @override
      void dispose() {
        first.dispose();
        second.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return SizedBox(
          width: 200,
          child: Column(
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  ListenableBuilder(
                      listenable: first,
                      builder: (context, child) {
                        return Text("${first.i}");
                      }),
                  TextButton(
                    onPressed: () {
                      first.increment();
                    },
                    child: Text("First"),
                  ),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  ListenableBuilder(
                      listenable: second,
                      builder: (context, child) {
                        return Text("${second.i}");
                      }),
                  TextButton(
                    onPressed: () {
                      second.increment();
                    },
                    child: Text("Second"),
                  ),
                ],
              )
            ],
          ),
        );
      }
    }