【发布时间】:2020-07-10 17:01:32
【问题描述】:
在我的应用程序中,我尝试使用AnimatedIcon 而不是Appbar、leading 图标来更改AnimatedIcon 的控制器我正在使用Provider 包,但我收到此错误:
setState() or markNeedsBuild() called during build.
我的AppBar:
AppBar(
elevation: 8.0,
titleSpacing: 0.0,
automaticallyImplyLeading: true,
leading: Consumer<AppBarAnimatedIconMode>(
builder: (context, mode, child) => ValueListenableProvider.value(
value: mode.iconMode,
child: Consumer<bool>(
builder: (context, value, child) => AppBarAnimatedIcon(
animate: value,
)))),
AppBarAnimatedIcon类:
class AppBarAnimatedIcon extends StatefulWidget {
final bool animate;
const AppBarAnimatedIcon({@required this.animate});
@override
State<StatefulWidget> createState() => _AppBarAnimatedIcon();
}
class _AppBarAnimatedIcon extends State<AppBarAnimatedIcon> with TickerProviderStateMixin {
AnimationController _animationController;
bool get _animate => widget.animate;
@override
void initState() {
super.initState();
_animationController = AnimationController(vsync: this, duration: const Duration(milliseconds: 500));
if(_animate){
_animationController.forward();
}else{
_animationController.reverse();
}
}
@override
Widget build(BuildContext context) {
return Center(
child: AnimatedIcon(
icon: AnimatedIcons.menu_close,
progress: _animationController,
),
);
}
}
ValueNotifier类改AnimatedIcon动画控制器:
class AppBarAnimatedIconMode {
final ValueNotifier<bool> iconMode = ValueNotifier<bool>(false);
// ignore: use_setters_to_change_properties
void changeIconMode() {
iconMode.value = !iconMode.value;
}
}
完整的错误信息:
This _DefaultInheritedProviderScope<bool> 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.
The widget on which setState() or markNeedsBuild() was called was: _DefaultInheritedProviderScope<bool>
value: false
The widget which was currently being built when the offending call was made was: BuildDefaultAppBar
dirty
dependencies: [_EffectiveTickerMode]
state: _BuildDefaultAppBar#a5ab5(tickers: tracking 1 ticker)
When the exception was thrown, this was the stack:
#0 Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:4167:11)
#1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4182:6)
#2 _InheritedProviderScopeMixin.markNeedsNotifyDependents (package:provider/src/inherited_provider.dart:269:5)
#3 _DeferredDelegateState.setState (package:provider/src/deferred_inherited_provider.dart:139:17)
#4 ValueListenableProvider._startListening.<anonymous closure>.<anonymous closure> (package:provider/src/value_listenable_provider.dart:74:38)
...
The ValueNotifier<bool> sending notification was: ValueNotifier<bool>#7aa18(true)
【问题讨论】:
-
改用
SingleTickerProviderStateMixin,它对您的情况更有效。 -
@mFeinstein 我又出错了
-
我不确定您发布的代码的问题是什么,但我认为这与您使用 Provider 包的方式有关,您使用它太多了,您不能简化一下吗?
-
@mFeinstein 我想是的,我可以,你熟悉
Provider吗? -
我是,我将首先检查 changeIconMode(),特别是当您忽略警告时
标签: flutter flutter-layout flutter-provider