Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listening to a variable change in flutter

Tags:

I'm trying to listen to a variable change to execute some code. So the variable is a bool named reset. I want to execute something (say reset the animation controller) once the animation ends OR a button (from another widget) is pressed. Executing something when the animation ends works as once it ends AnimationStatus.dismissed will be its state and the listener will be called. This then allows me to use a callback function onCountdownexpire in order to set the variable reset accordingly and based on what it is set, execute some code in the if(widget.reset) block. So there is no need to listen for this case.

Problem:

However, lets say a button is pressed (in another widget) and I set the variable reset to true. I want the animation to stop and reset. I cannot now depend on the AnimationStatus listener as it only executes when there is a state change. I want it to reset during its state. So I have to somehow listen to the variable widget.reset.

I have done some research on this and found out that ValueNotifier might be a way to go but there are not a lot of examples on how to go about using it. Like how do I go about listening to it ?

Code:

class Countdown extends StatefulWidget {    final VoidCallback onCountdownExpire;   bool reset;   Countdown(this.onCountdownExpire);    @override   CountdownState createState() => CountdownState(); }  class CountdownState extends State<Countdown> with TickerProviderStateMixin {   AnimationController controller;    String get timerString {     Duration duration = controller.duration * controller.value;     return '${duration.inMinutes}:${(duration.inSeconds % 60).toString()}';   }    @override   void initState() {     super.initState();     controller = AnimationController(       vsync: this,       duration: Duration(seconds: 2),     )..addStatusListener((AnimationStatus status){         if (status == AnimationStatus.dismissed) {           debugPrint("Animation.dismissed");           widget.onCountdownExpire();           if (widget.reset) {             widget.reset = false;             controller.reverse(from: 1.0);           }          }     });     controller.reverse(from: 1.0);   }   ... // omitted code } 

What I have tried but it does not seem to be working as expected:

class Countdown extends StatefulWidget {    final VoidCallback onCountdownExpire;   Countdown(this.onCountdownExpire);   ValueNotifier reset = ValueNotifier(false);    @override   CountdownState createState() => CountdownState(); }  class CountdownState extends State<Countdown> with TickerProviderStateMixin {   AnimationController controller;    @override   void initState() {      widget.reset.addListener(() {       debugPrint("value notifier is true");       controller.reverse(from: 1.0);     });      super.initState();      controller = AnimationController(       vsync: this,       duration: Duration(seconds: 2),     )..addStatusListener((AnimationStatus status){         if (status == AnimationStatus.dismissed) {           debugPrint("Animation.dismissed");           widget.onCountdownExpire();         }     });     controller.reverse(from: 1.0);   }   ... // omitted code } 

Update: The solution (above) was actually working, I just had to use something like this to notify the listener:

countdown.reset.notifyListeners(); // OR countdown.reset.value = true;   
like image 965
Rajdeep Avatar asked Jun 03 '19 06:06

Rajdeep


People also ask

How do you use change notifier in flutter?

ChangeNotifier is a class that provides change notification to its listeners. That means you can subscribe to a class that is extended or mixed in with ChangeNotifier and call its notifyListeners() method when there's a change in that class.

What is ValueNotifier flutter?

ValueNotifier is a special type of class that extends Changenotifier, which can hold a single value and notifies the widgets which are listening to it whenever its holding value gets change. ChangeNotifier is a class that provides change notification to its listeners.


1 Answers

OP already got an answer in the comments. I'm just typing it here so the question is correctly marked as answered.

Just notify the listener:

countdown.reset.notifyListeners(); // OR countdown.reset.value = true; 

Credit to @pskink

like image 97
ambiguous58 Avatar answered Sep 19 '22 07:09

ambiguous58