我收到此错误:
I/flutter (29346): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ I/flutter (29346): The following assertion was thrown building MainLogic(dirty, state: _MainLogic#9c794): I/flutter (29346): setState() or markNeedsBuild() called during build. I/flutter (29346): This InhWidget widget cannot be marked as needing to build because the framework is already in the I/flutter (29346): process of building widgets. A widget can be marked as needing to be built during the build phase I/flutter (29346): only if one of its ancestors is currently building. This exception is allowed because the framework I/flutter (29346): builds parent widgets before children, which means a dirty descendant will always be built. I/flutter (29346): Otherwise, the framework might not visit this widget during this build phase. I/flutter (29346): The widget on which setState() or markNeedsBuild() was called was: I/flutter (29346): InhWidget(state: InhState#3aaa8) I/flutter (29346): The widget which was currently being built when the offending call was made was: I/flutter (29346): MainLogic(dirty, state: _MainLogic#9c794)
在用代码充斥您之前,我想解释一下背后的逻辑:我正在尝试实施百家乐游戏的规则,为此,我设置了一个继承的小部件,一些无状态的小部件将输入发送到存储的对象在继承状态下,其他对象将根据此对象数据重新构建自己。
我做的最后一个更改是应用百家乐“绘图规则”,可以使Object在需要时跳过输入,但是当发生这种情况时,继承的小部件不喜欢它。
我将发布代码的最后一部分,但是如果您认为其他相关的内容,请提出问题,然后我将其发布。
预先感谢您的帮助
class MainLogic extends StatefulWidget { @override State<StatefulWidget> createState() => new _MainLogic(); } class _MainLogic extends State<MainLogic> { Widget cardGrid = CardGrid(); Widget newGame = NewGame(); Rules rules; bool gameOver; @override void initState(){ super.initState(); gameOver = false; } @override Widget build(BuildContext context) { final InhState state = InhWidget.of(context); rules = new Rules(game:state.game); if(gameOver==false && state.game.count>3 && rules.playerExtraCard()==false) {state.skip();} if(gameOver==false && state.game.count>4 && rules.bankerExtraCard()==false) {state.skip();} checkGame(state.game.count); return Container(child:status(gameOver)); } status(bool _gameOver) { Widget whichOne; if (_gameOver) {whichOne=newGame;} else {whichOne=cardGrid;} return whichOne; } void checkGame(int cards) { if (cards >= 6) { gameOver = true; } else {gameOver = false;} }
…
class Rules { final Game game; Rules({this.game}); static Deck deck = new Deck(); int get p1 => deck.getValue(game.p1); int get p2 => deck.getValue(game.p2); int get p3 => deck.getValue(game.p3); int get b1 => deck.getValue(game.b1); int get b2 => deck.getValue(game.b2); int get b3 => deck.getValue(game.b3); normalize(List<int> input) { int normal; int initial = 0; input.forEach((num e){initial += e;}); if(initial>9) {normal=initial-10;} else {normal=initial;} return normal; } playerExtraCard() { bool extraCard; int pInit = normalize([p1,p2]); int bInit = normalize([b1+b2]); if (pInit > 5) {extraCard = false;} else if (bInit > 7) {extraCard = false;} else {extraCard = true;} return extraCard; } bankerExtraCard() { bool extraCard; int pInit = normalize([p1,p2]); int bInit = normalize([b1+b2]); int pWing = normalize([p3]); if (pInit>7) {extraCard = false;} else if (bInit>6) {extraCard = false;} else if (pInit>5 && bInit<6) {extraCard = true;} else if (pInit<6 && bInit==6 && pWing<8 && pWing>5) {extraCard = true;} else if (pInit<6 && bInit==5 && pWing<8 && pWing>3) {extraCard = true;} else if (pInit<6 && bInit==4 && pWing<8 && pWing>1) {extraCard = true;} else if (pInit<6 && bInit==3 && pWing==8) {extraCard = true;} else if (pInit<6 && bInit<3) {extraCard = true;} else {extraCard = false;} return extraCard; } }
class InhState extends State<InhWidget> { Game game = new Game(); @override void initState() { super.initState(); game.blank(); } void deal(String card) { setState(() { game.cards[game.count] = card; game.count = game.count + 1; }); } void restart(){ setState(() { game.blank(); }); } void skip() { setState(() { game.count = game.count + 1; }); } @override Widget build(BuildContext context) { return new InhCore( data: this, child: widget.child, ); } }
class InhWidget extends StatefulWidget { InhWidget({this.child}); final Widget child; @override State<StatefulWidget> createState() => InhState(); static InhState of(BuildContext context) { return (context.inheritFromWidgetOfExactType(InhCore) as InhCore).data; } }
你打电话state.skip()的build(),并setState()在skip()
state.skip()
build()
setState()
skip()
void skip() { setState(() { game.count = game.count + 1; }); }
通常,最好避免使用中的“业务逻辑” build()。
不应该有一个需要计算所有的东西,你用InhState在build()。build()可以在不同时间被频繁调用。
InhState
您应该根据用户交互事件(onTap:,…)或其他事件源(例如流或Future来指示异步操作的状态更改)来更新状态。
onTap: