21

Actually I am working on Login page with Bloc. So when I press submit button, it does business logic on bloc then trying to navigate to home page based on the result. I tried this

Widget submitButton() {
    return StreamBuilder(
      stream: bloc.submitStream,
      builder: (context, snapshot) {
        if (snapshot.data == "Success") {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => RegisterPage(),
            ),
          );
        }
        return RaisedButton(
          child: Text("Submit"),
          onPressed: () {
            bloc.submitSink.add(null);
          },
        );
      },
    );
  }

But I got error like this The widget which was currently being built when the offending call was made....

Later then I found two solution: 1. Using SchedulerBinding, 2. Using WidgetsBinding. So what is the difference between SchedulerBinding and WidgetsBinding. Which one do I have to use?

Full Error Log:

I/flutter (17893): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (17893): The following assertion was thrown building LayoutBuilder:
I/flutter (17893): setState() or markNeedsBuild() called during build.
I/flutter (17893): This Overlay widget cannot be marked as needing to build because the framework is already in the
I/flutter (17893): process of building widgets. A widget can be marked as needing to be built during the build phase
I/flutter (17893): only if one of its ancestors is currently building. This exception is allowed because the framework
I/flutter (17893): builds parent widgets before children, which means a dirty descendant will always be built.
I/flutter (17893): Otherwise, the framework might not visit this widget during this build phase.
I/flutter (17893): The widget on which setState() or markNeedsBuild() was called was:
I/flutter (17893):   Overlay-[LabeledGlobalKey<OverlayState>#70089](state: OverlayState#3bf13(entries:
I/flutter (17893):   [OverlayEntry#9280a(opaque: false; maintainState: false), OverlayEntry#1af87(opaque: false;
I/flutter (17893):   maintainState: true), OverlayEntry#9fb49(opaque: false; maintainState: false),
I/flutter (17893):   OverlayEntry#87589(opaque: false; maintainState: true)]))
I/flutter (17893): The widget which was currently being built when the offending call was made was:
I/flutter (17893):   LayoutBuilder(renderObject: _RenderLayoutBuilder#d3baf relayoutBoundary=up1 NEEDS-LAYOUT
I/flutter (17893):   NEEDS-PAINT)
I/flutter (17893): 
I/flutter (17893): When the exception was thrown, this was the stack:
I/flutter (17893): #0      Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:3497:11)
I/flutter (17893): #1      Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:3523:6)
I/flutter (17893): #2      State.setState (package:flutter/src/widgets/framework.dart:1138:14)
I/flutter (17893): #3      OverlayState.insertAll (package:flutter/src/widgets/overlay.dart:301:5)
I/flutter (17893): #4      OverlayRoute.install (package:flutter/src/widgets/routes.dart:43:24)
I/flutter (17893): #5      TransitionRoute.install (package:flutter/src/widgets/routes.dart:184:11)
I/flutter (17893): #6      ModalRoute.install (package:flutter/src/widgets/routes.dart:899:11)
I/flutter (17893): #7      NavigatorState.push (package:flutter/src/widgets/navigator.dart:1672:11)
I/flutter (17893): #8      Navigator.push (package:flutter/src/widgets/navigator.dart:1011:34)
I/flutter (17893): #9      _SetPinPageState.submitButton (package:technicalreport/screens/set_pin_page.dart:94:15)
I/flutter (17893): #10     _SetPinPageState.build.<anonymous closure>.<anonymous closure> (package:technicalreport/screens/set_pin_page.dart:52:29)
I/flutter (17893): #11     OrientationBuilder._buildWithConstraints (package:flutter/src/widgets/orientation_builder.dart:48:12)
I/flutter (17893): #12     _LayoutBuilderElement._layout.<anonymous closure> (package:flutter/src/widgets/layout_builder.dart:111:26)
I/flutter (17893): #13     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2253:19)
I/flutter (17893): #14     _LayoutBuilderElement._layout (package:flutter/src/widgets/layout_builder.dart:107:11)
I/flutter (17893): #15     RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:1728:58)
I/flutter (17893): #16     PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:797:15)
I/flutter (17893): #17     RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:1728:13)
I/flutter (17893): #18     _RenderLayoutBuilder.performLayout (package:flutter/src/widgets/layout_builder.dart:205:5)
I/flutter (17893): #19     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #20     MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:142:11)
I/flutter (17893): #21     _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:350:7)
I/flutter (17893): #22     MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:212:7)
I/flutter (17893): #23     RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:356:14)
I/flutter (17893): #24     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #25     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #26     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #27     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #28     _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1206:11)
I/flutter (17893): #29     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #30     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #31     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #32     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #33     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #34     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #35     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #36     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #37     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #38     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #39     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #40     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #41     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #42     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #43     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #44     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #45     RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:3032:13)
I/flutter (17893): #46     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #47     RenderStack.performLayout (package:flutter/src/rendering/stack.dart:510:15)
I/flutter (17893): #48     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #49     __RenderTheatre&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #50     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #51     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #52     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #53     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #54     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #55     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #56     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #57     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17893): #58     RenderObject.layout (package:flutter/src/rendering/object.dart:1632:7)
I/flutter (17893): #59     RenderView.performLayout (package:flutter/src/rendering/view.dart:151:13)
I/flutter (17893): #60     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1507:7)
I/flutter (17893): #61     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:766:18)
I/flutter (17893): #62     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:329:19)
I/flutter (17893): #63     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:701:13)
I/flutter (17893): #64     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:268:5)
I/flutter (17893): #65     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:988:15)
I/flutter (17893): #66     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:928:9)
I/flutter (17893): #67     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:749:7)
I/flutter (17893): #76     _Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:382:19)
I/flutter (17893): #77     _Timer._handleMessage (dart:isolate/runtime/libtimer_impl.dart:416:5)
I/flutter (17893): #78     _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
I/flutter (17893): (elided 8 frames from package dart:async)
I/flutter (17893): ════════════════════════════════════════════════════════════════════════════════════════════════════
D/        (17893): HostConnection::get() New Host Connection established 0xa0ba6b40, tid 17931
D/EGL_emulation(17893): eglMakeCurrent: 0xa3508c40: ver 2 0 (tinfo 0x9084ab40)
Crazy Lazy Cat
  • 13,595
  • 4
  • 30
  • 54
  • Can you show the whole error message? – ZeRj May 23 '19 at 13:10
  • Thank ZeRj. I added full error message. – Crazy Lazy Cat May 24 '19 at 09:41
  • Technically, you don't need either one. You need to refactor your code. Make your stream a broadcast stream, and add a listener to your stream (probably in the initState lifecycle callback) and navigate to the `RegisterPage` from there. You need to get the offending code outside the build lifecycle. – bentesha Mar 25 '21 at 16:51

2 Answers2

30

There are three callbacks available in flutter which rendering flutter widgets.

enter image description here

As noted in the docs at https://api.flutter.dev/flutter/scheduler/SchedulerBinding-mixin.html

Transient callbacks: triggered by the system’s [Window.onBeginFrame] callback, for synchronizing the application’s behavior to the system’s display. For example, [Ticker]s and [AnimationController]s trigger from these.

Persistent callbacks: triggered by the system’s [Window.onDrawFrame] callback, for updating the system’s display after transient callbacks have executed. For example, the rendering layer uses this to drive its rendering pipeline.

Post-frame callbacks: which are run after persistent callbacks, just before returning from the [Window.onDrawFrame] callback.

Non-rendering tasks, to be run between frames. These are given a priority and are executed in priority order according to a schedulingStrategy.

All above callbacks run sequentially, but for us, the last callback would work i.e Post-frame callbacks

Widgets Binding: The glue between the widgets layer and the Flutter engine. which comes with WidgetsBindingObserver mixin which has many callbacks but one which required to use is didChangeAppLifecycleState that returns AppLifecycleState.

Scheduler Binding: This is also similar to WidgetBinding but it does not provide any life cycle callbacks.

The below binding example would be called exactly the ones, means print statement like WidgetsBinding & SchedulerBinding will be printed only once as we called it initState(), but it will be called when build method finished it’s rendering.

void initState() {
  super.initState();
  print("initState");
  WidgetsBinding.instance.addPostFrameCallback((_) {
    print("WidgetsBinding");
  });
  SchedulerBinding.instance.addPostFrameCallback((_) {
    print("SchedulerBinding");
  });
}
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Jitesh Mohite
  • 31,138
  • 12
  • 157
  • 147
11

Both solutions do the same.

WidgetsBinding inherits this Method from SchedulerBinding https://api.flutter.dev/flutter/widgets/WidgetsBinding-mixin.html

It registers a callback that will be called after the frame is build. See in the docs: https://api.flutter.dev/flutter/scheduler/SchedulerBinding/addPostFrameCallback.html

ZeRj
  • 1,612
  • 14
  • 24