chrisedg87 / flutter_rounded_loading_button

A simple implementation of an animated loading button widget for Flutter
MIT License
328 stars 87 forks source link

Programmatically stop and start fails #47

Open alexlipa91 opened 3 years ago

alexlipa91 commented 3 years ago

I would like to start the button animation and stop it after a ModalBottom has been shown.

When the modal is shown, if I press outside the modal (basically it pops it from the stack) the button would continue to run. That is why I added controller.reset().

This works fine the first time. However if I do this same thing twice I get

I/flutter (25672): LateInitializationError: Field '_stopListener@67160650' has not been initialized.
I/flutter (25672): 
I/flutter (25672): #0      RoundedLoadingButtonController._stopListener (package:rounded_loading_button/rounded_loading_button.dart)
I/flutter (25672): #1      RoundedLoadingButtonController.stop (package:rounded_loading_button/rounded_loading_button.dart:313:5)
I/flutter (25672): #2      JoinGameButton.onPressed (package:nutmeg/screens/MatchDetailsModals.dart:575:16)
I/flutter (25672): <asynchronous suspension>

This is the onTap function for the button

Future<void> onTap(
      BuildContext context, RoundedLoadingButtonController controller) async {
      var paymentRecap = await PaymentController.generatePaymentRecap(
        matchesState, match.documentId, userState);
    await showModalBottomSheet(
         context: context,
         builder: (context) => PrepaymentBottomBar(
               match: match,
               recap: paymentRecap,
             ));

    controller.stop();

I have tried controller.stop() as well as controller.reset() but same outcome

chrisedg87 commented 3 years ago

Hi @alexlipa91, I'm struggling to reproduce this one. Would you be able to share a full example? . The listeners are registered during the InitState of the button, so it could be this isn't being called for some reason.

dragouf commented 2 years ago

I have the same problem. I get this error if I have multiple RoundedLoadingButtonController in the widget. Is it known issue ?

alexobviously commented 2 years ago

@chrisedg87 I also have a bunch of logs for this error in Sentry, although I haven't been able to reproduce it myself. We also have several RoundedLoadingButtonControllers on one page.

Looking through the code, it's possible that this line:

widget.controller._addListeners(_start, _stop, _success, _error, _reset);

needs to be further up. I don't use BehaviorSubject much myself, but my understanding is that when a listener is registered to one, it immediately emits the last state that was in it. In initState there are a few things being listened to, and maybe it could be that under some strange conditions, one of these contains an event that tries to trigger a listener that hasn't been initialised yet, before the end of initState is even reached.

I could be wrong but it's worth a look.

tamoyal commented 2 years ago

@chrisedg87 I think the issue is when you call stop on a controller where the button widget has not been initialized. So let's say you have a grid of buttons, I dunno ....like 8 of them. So you instantiate 8 controllers. But maybe because of some app logic you don't build the actual buttons - only 4 of them are showing. If you try to stop any of the 4 that were never rendered, you'll get this error. We can track it on our end but it's a bit annoying where an alternative of just not stopping a button that has no stop listener seems better. (cc @alexobviously)