Flutter - StreamBuilder builder function runs when

2019-07-23 06:59发布

问题:

I have a widget called RootContainer which receives a Widget child and wrap it inside a StreamBuilder:

class RootContainer extends StatelessWidget {
  final Widget child;

  RootContainer({this.child});

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<OverlayAlert>(
      stream: ApiService.ThrottledException.stream,
      builder: (context, snapshot) {

        if (snapshot.connectionState == ConnectionState.active) {
          Future.delayed(Duration.zero, () => showAlert(context, snapshot));
        }

        return this.child;
      },
    );
  }

  void showAlert(BuildContext context, snapshot) {
    print("showing dialog");
    showDialog(
      context: context,
      builder: (context) => OverlayAlertDialog(snapshot),
    );
  }

When an error occurs, I add a new value to the stream ApiService.exception.stream which triggers the StreamBuilder builder and then it opens a dialog.

This is the current widget tree:

The problem starts when I want to pop the navigator, the StreamBuilder.builder builds again!

  1. I thought it may happen because the RootContainer is being rebuilt, but placing a print before the StreamBuilder has resulted in just one print.

  2. I tried to .listen to the stream, and the stream didn't fire when I popped the navigator so I can confirm that there's nothing wrong with ApiService.ThrottledException.stream.

  3. The snapshot when the navigator is popped is equal (the data) to the last emission.

You can see in the following demo that whenever I press the back button the dialog pops up again:

What could cause the StreamBuilder to rebuild itself when I press on the back button?

回答1:

I had to change RootContainer to extend StatefulWidget instead of StatelessWidget.

I have no idea what's happening behind the scene, but it works! Any explanation would be nice.