Flutter onStretchTrigger not working. Build scheduled during frame

Issue

This code will work completely fine if I use Refresh indicator OR Button tap.

But wont work if use it inside SliverAppBar for onStretchTrigger function.

onStretchTrigger: () async {
 setState(() {
 myVariable = myFutureData();
 });
},

The error I get:

I/flutter (31102): Build scheduled during frame.

I/flutter (31102): While the widget tree was being built, laid out,
and painted, a new frame was scheduled to rebuild the widget tree.

I/flutter (31102): This might be because setState() was called from a
layout or paint callback. If a change is needed to the widget tree, it
should be applied as the tree is being built. Scheduling a change for
the subsequent frame instead results in an interface that lags behind
by one frame. If this was done to make your build dependent on a size
measured at layout time, consider using a LayoutBuilder,
CustomSingleChildLayout, or CustomMultiChildLayout.

If, on the other hand, the one frame delay is the desired effect, for
example because this is an animation, consider scheduling the frame in
a post-frame callback using SchedulerBinding.addPostFrameCallback or
using an AnimationController to trigger the animation. I/flutter
(31102): I/flutter (31102): #0
WidgetsBinding._handleBuildScheduled.
package:flutter/…/widgets/binding.dart:747

I/flutter (31102): #1 WidgetsBinding._handleBuildScheduled
package:flutter/…/widgets/binding.dart:770

I/flutter (31102): #2 BuildOwner.scheduleBuildFor
package:flutter/…/widgets/framework.dart:2476

I/flutter (31102): #3 Element.markNeedsBuild
package:flutter/…/widgets/framework.dart:4324

I/flutter (31102): #4 State.setState
package:flutter/…/widgets/framework.dart:1108

I/flutter (31102): #5 _HomeScreenState.build.
package:fesale/screens/screen_home.dart:197

I/flutter (31102): #6 _HomeScreenState.build.
package:fesale/screens/screen_home.dart:195

I/flutter (31102): #7 RenderSliverPersistentHeader.layoutChild
package:flutter/…/rendering/sliver_persistent_header.dart:257

I/flutter (31102): #8
RenderSliverFloatingPersistentHeader.performLayout
package:flutter/…/rendering/sliver_persistent_header.dart:708

I/flutter (31102): #9 RenderObject.layout
package:flutter/…/rendering/object.dart:1858

I/flutter (31102): #10 RenderViewportBase.layoutChildSeq

Please help could not find any solution for that 🙁

Solution

INITIAL: First of all: you don’t need to put an async there since you are not making use of the await keyword, it’s just a function call which return value is being assigned to your variable.

UPDATE: onStretchTrigger actually expects an AsyncCallback so for this use case the async keyword has to be used – sorry!


Second: your error message states what causes this and offers several solution:

[…] This might be because setState() was called from a layout or paint callback. […] consider scheduling the frame in a post-frame callback using SchedulerBinding.addPostFrameCallback […]

So for now you can do:

SchedulerBinding.instance?.addPostFrameCallback((_) {
  setState(() => myVariable = myFutureData());
});

Answered By – kounex

Answer Checked By – Marie Seifert (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *