setState() or markNeedsBuild() called during build. this overlay widget cannot be marked as needing to build

3,712

You are receiving this error because you are doing something before the page build is finished. So you have to wait for that.

How about using the addPostFrameCallback?

See this information from the official flutter docs.

Schedule a callback for the end of this frame.

Does not request a new frame.

This callback is run during a frame, just after the persistent frame callbacks (which is when the main rendering pipeline has been flushed). If a frame is in progress and post-frame callbacks haven't been executed yet, then the registered callback is still executed during the frame. Otherwise, the registered callback is executed during the next frame.

The callbacks are executed in the order in which they have been added.

Post-frame callbacks cannot be unregistered. They are called exactly once.

So you could do:

  SchedulerBinding.instance.addPostFrameCallback((_) {
    //yourcode
  });

Another reason might be (hard to tell without seeing your entire code) that you are executing an onPressed or onTap callback immediatly during your buildphase. Make sure you don't have anything like onTap: onTap() in your code. Instead you need to do onTap: onTap.

Share:
3,712
Liron Abutbul
Author by

Liron Abutbul

Updated on December 27, 2022

Comments

  • Liron Abutbul
    Liron Abutbul over 1 year

    I tried to script animated dialog with 'showGeneralDialog' inside SetState() of 'fling' function called by {AbsorbPointer} (specifically {GestureDetector} onPanEnd). I attached the simple code, I tried to do it with future async await, etc but probably I don't get it.

    'child: EasyDialog' defined in my code as void function. Here's my debug console and code attached

    I'd be glad if anyone can guide me how animation (pageBuilder) can be done during the setState.

    [38;5;248m════════ Exception caught by widgets library ═══════════════════════════════════[39;49m
    [38;5;244mThe following assertion was thrown building Builder(dirty, dependencies: [_LocalizationsScope-[GlobalKey#3e9b6]]):[39;49m
    setState() or markNeedsBuild() called during build.
    
    [38;5;244mThis Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets.  A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.[39;49m
    [38;5;244mThe widget on which setState() or markNeedsBuild() was called was: Overlay-[LabeledGlobalKey<OverlayState>#2acd6][39;49m
        [38;5;244mstate: OverlayState#6a2d6(entries: [OverlayEntry#9eb98(opaque: true; maintainState: false), OverlayEntry#7538d(opaque: false; maintainState: true), OverlayEntry#dfb68(opaque: true; maintainState: false), OverlayEntry#12c39(opaque: false; maintainState: true), OverlayEntry#3ef90(opaque: true; maintainState: false), OverlayEntry#53522(opaque: false; maintainState: true), OverlayEntry#07377(opaque: false; maintainState: false), OverlayEntry#e5cbf(opaque: false; maintainState: true), OverlayEntry#f3375(opaque: false; maintainState: false), OverlayEntry#b6bdc(opaque: false; maintainState: true), OverlayEntry#34ca0(opaque: false; maintainState: false)])[39;49m
    [38;5;244mThe widget which was currently being built when the offending call was made was: Builder[39;49m
        [38;5;244mdirty[39;49m
        [38;5;244mdependencies: [_LocalizationsScope-[GlobalKey#3e9b6]][39;49m
    [38;5;244mThe relevant error-causing widget was[39;49m
    [38;5;248mSlideTransition[39;49m
     lib\main.dart
    [38;5;244mWhen the exception was thrown, this was the stack[39;49m
    [38;5;244m#0      Element.markNeedsBuild.<anonymous closure>[39;49m
     package:flutter/…/widgets/framework.dart
    [38;5;244m#1      Element.markNeedsBuild[39;49m
     package:flutter/…/widgets/framework.dart
    [38;5;244m#2      State.setState[39;49m
     package:flutter/…/widgets/framework.dart
    [38;5;244m#3      OverlayState.rearrange[39;49m
     package:flutter/…/widgets/overlay.dart
    [38;5;244m#4      NavigatorState._flushHistoryUpdates[39;49m
     package:flutter/…/widgets/navigator.dart
    [38;5;244m...[39;49m
    [38;5;248m════════════════════════════════════════════════════════════════════════════════[39;49m
    E/flutter (30352): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 2976 pos 18: '!navigator._debugLocked': is not true.
    [38;5;244mE/flutter (30352): #0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)[39;49m
    [38;5;244mE/flutter (30352): #1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)[39;49m
    [38;5;244mE/flutter (30352): #2      _RouteEntry.handlePush.<anonymous closure>[39;49m
     package:flutter/…/widgets/navigator.dart
    [38;5;244mE/flutter (30352): #3      TickerFuture.whenCompleteOrCancel.thunk[39;49m
     package:flutter/…/scheduler/ticker.dart
    [38;5;244mE/flutter (30352): #4      _rootRunUnary (dart:async/zone.dart:1194:47)[39;49m
    [38;5;244mE/flutter (30352): #5      _CustomZone.runUnary (dart:async/zone.dart:1097:19)[39;49m
    [38;5;244mE/flutter (30352): #6      _FutureListener.handleValue (dart:async/future_impl.dart:150:18)[39;49m
    [38;5;244mE/flutter (30352): #7      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:703:45)[39;49m
    [38;5;244mE/flutter (30352): #8      Future._propagateToListeners (dart:async/future_impl.dart:732:32)[39;49m
    [38;5;244mE/flutter (30352): #9      Future._completeWithValue (dart:async/future_impl.dart:536:5)[39;49m
    [38;5;244mE/flutter (30352): #10     Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:574:7)[39;49m
    [38;5;244mE/flutter (30352): #11     _rootRun (dart:async/zone.dart:1186:13)[39;49m
    [38;5;244mE/flutter (30352): #12     _CustomZone.run (dart:async/zone.dart:1090:19)[39;49m
    [38;5;244mE/flutter (30352): #13     _CustomZone.runGuarded (dart:async/zone.dart:994:7)[39;49m
    [38;5;244mE/flutter (30352): #14     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1034:23)[39;49m
    [38;5;244mE/flutter (30352): #15     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)[39;49m
    [38;5;244mE/flutter (30352): #16     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)[39;49m
    E/flutter (30352):
    E/flutter (30352): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 2976 pos 18: '!navigator._debugLocked': is not true.
    [38;5;244mE/flutter (30352): #0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)[39;49m
    [38;5;244mE/flutter (30352): #1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)[39;49m
    [38;5;244mE/flutter (30352): #2      _RouteEntry.handlePush.<anonymous closure>[39;49m
     package:flutter/…/widgets/navigator.dart
    [38;5;244mE/flutter (30352): #3      TickerFuture.whenCompleteOrCancel.thunk[39;49m
     package:flutter/…/scheduler/ticker.dart
    [38;5;244mE/flutter (30352): #4      _rootRunUnary (dart:async/zone.dart:1194:47)[39;49m
    [38;5;244mE/flutter (30352): #5      _CustomZone.runUnary (dart:async/zone.dart:1097:19)[39;49m
    [38;5;244mE/flutter (30352): #6      _FutureListener.handleValue (dart:async/future_impl.dart:150:18)[39;49m
    [38;5;244mE/flutter (30352): #7      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:703:45)[39;49m
    [38;5;244mE/flutter (30352): #8      Future._propagateToListeners (dart:async/future_impl.dart:732:32)[39;49m
    [38;5;244mE/flutter (30352): #9      Future._completeWithValue (dart:async/future_impl.dart:536:5)[39;49m
    [38;5;244mE/flutter (30352): #10     Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:574:7)[39;49m
    [38;5;244mE/flutter (30352): #11     _rootRun (dart:async/zone.dart:1186:13)[39;49m
    [38;5;244mE/flutter (30352): #12     _CustomZone.run (dart:async/zone.dart:1090:19)[39;49m
    [38;5;244mE/flutter (30352): #13     _CustomZone.runGuarded (dart:async/zone.dart:994:7)[39;49m
    [38;5;244mE/flutter (30352): #14     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1034:23)[39;49m
    [38;5;244mE/flutter (30352): #15     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)[39;49m
    [38;5;244mE/flutter (30352): #16     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)[39;49m
    E/flutter (30352):
    I/ViewRootImpl@738e9ee[MainActivity](30352): ViewPostIme pointer 0
    
      fling(details) {
        final simulation = FrictionSimulation(/**/
    
        );
        _spinController.animateWith(simulation).then((_) => setState(() {
              absorbing = false;
              Timer(Duration(milliseconds: 500), () {
                showGeneralDialog(
                  barrierLabel: "Label",
                  barrierDismissible: true,
                  barrierColor: Colors.black.withOpacity(0.5),
                  transitionDuration: Duration(milliseconds: 700),
                  context: context,
                  pageBuilder: (context, anim1, anim2) {
                    return Align(
                      alignment:
                          _fromTop ? Alignment.topCenter : Alignment.bottomCenter,
                      child: Container(
                        height: 300,
                        child: SizedBox.expand(
                            child: EasyDialog(
                          closeButton: true,
                          cardColor: Colors.white.withOpacity(0.3),
                          contentPadding: const EdgeInsets.only(bottom: 100),
                          title: Text(
                            "Task Dialog",
                            textScaleFactor: 1.2,
                          ),
                          description: Text(
                            text[Random().nextInt(text.length)],
                          ),
                          topImage: AssetImage('assets/images/cbg82.jpg'),
                          height: 400,
                          width: 350,
                        ).show(context)),
                        margin: EdgeInsets.only(
                            top: 50, left: 12, right: 12, bottom: 50),
                        decoration: BoxDecoration(
                          color: Colors.white,
                          borderRadius: BorderRadius.circular(40),
                        ),
                      ),
                    );
                  },
                  transitionBuilder: (context, anim1, anim2, child) {
                    return SlideTransition(
                      position: Tween(
                              begin: Offset(0, _fromTop ? -1 : 1),
                              end: Offset(0, 0))
                          .animate(anim1),
                      child: child,
                    );
                  },
                );
              });
            }));
        setState(() => absorbing = true);
      }
    ///
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
        /*appbars*/
          body: Container(
              child: Column(
                children: <Widget>[
                  Card(
                      child: AbsorbPointer(
                        absorbing: absorbing,
                        child: GestureDetector(
                          behavior: HitTestBehavior.translucent,
                          onPanUpdate: (d) =>
                              _spinController.value += d.delta.dx / 100,
                          onPanEnd: fling,
                          child: SizedBox(
                            child: RotationTransition(
                                turns: _spinController,
                                child: FittedBox(
                                    alignment: Alignment.center,
                                    fit: BoxFit.fill,
                                    child: Image.asset(
                                      _imageToShow,
                                      height: _aHeight,
                                      width: _aWidth,
                                    ))),
                          ),
                        ),
                      )),
                ],
              )),
        );
      }
    

    Thanks :)

  • Liron Abutbul
    Liron Abutbul over 3 years
    Already tried to solve this with SchedulerBinding (maybe iI didn't do it right) and it did'nt work, I edited my post and added the code without unnecessary codes, If you please to take a look. Thanks!