Flutter onStretchTrigger 不工作。在帧期间安排构建
Flutter onStretchTrigger not working. Build scheduled during frame
如果我使用刷新指示器或点击按钮,此代码将完全正常工作。
但如果在 SliverAppBar 中用于 onStretchTrigger 函数.
,将无法工作
onStretchTrigger: () async {
setState(() {
myVariable = myFutureData();
});
},
我得到的错误:
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
请帮助找不到任何解决方案:(
INITIAL:首先:您不需要在此处放置 async
,因为您没有使用 await
关键字,这只是一个函数调用,将 return 值分配给您的变量。
UPDATE:onStretchTrigger
实际上需要一个 AsyncCallback
所以对于这个用例必须使用 async
关键字 - 抱歉!
其次:您的错误消息说明了导致此问题的原因并提供了几种解决方案:
[...] 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 [...]
所以现在你可以做:
SchedulerBinding.instance?.addPostFrameCallback((_) {
setState(() => myVariable = myFutureData());
});
如果我使用刷新指示器或点击按钮,此代码将完全正常工作。
但如果在 SliverAppBar 中用于 onStretchTrigger 函数.
,将无法工作onStretchTrigger: () async {
setState(() {
myVariable = myFutureData();
});
},
我得到的错误:
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:747I/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:708I/flutter (31102): #9 RenderObject.layout package:flutter/…/rendering/object.dart:1858
I/flutter (31102): #10 RenderViewportBase.layoutChildSeq
请帮助找不到任何解决方案:(
INITIAL:首先:您不需要在此处放置 async
,因为您没有使用 await
关键字,这只是一个函数调用,将 return 值分配给您的变量。
UPDATE:onStretchTrigger
实际上需要一个 AsyncCallback
所以对于这个用例必须使用 async
关键字 - 抱歉!
其次:您的错误消息说明了导致此问题的原因并提供了几种解决方案:
[...] 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 [...]
所以现在你可以做:
SchedulerBinding.instance?.addPostFrameCallback((_) {
setState(() => myVariable = myFutureData());
});