Flutter setState() is not updating a Flame SpriteAnimationWidget
This was actually a bug, we are fixing it here.
Meanwhile, as a workaround, you can change the key of the widget every time that you change the animation and it should update the widget.
Andy K
Updated on January 02, 2023Comments
-
Andy K over 1 year
I am currently using a SpriteAnimationWidget from Flame, and I want to have different animations by clicking buttons.
To test out if this works, I am changing the animation parameter of the SpriteAnimationWidget with a button click. After 1 second, the widget has to return to its original animation.
Here is my code:
Future<void> playReaction() async { setState(() { isPlaying = true; state = 'reaction'; }); await Future.delayed(Duration(milliseconds: 1000)); setState(() { isPlaying = false; state = 'idle'; }); }
And inside the build, I am returning:
if(state == 'reaction') { spriteAnimation = reactionSprite!.createAnimation(row: 0, stepTime: 0.1, from: 0, to: 10); print('reaction'); } else if(state == 'idle'){ spriteAnimation = sprite!.createAnimation(row: 1, stepTime: 0.2, from: 0, to: 4); print('idle'); } return Container( height: widget.size, child: Stack( fit: StackFit.expand, children: [ Positioned.fill( child: SpriteAnimationWidget( animation: spriteAnimation!, anchor: Anchor.center, ) ), ] ), );
The variables sprite and reactionSprite are sprite sheets that I preload using SpriteSheet.fromColumnsAndRows().
The problem is that, although my app successfully runs playReaction() and reaches print('reaction'), the SpriteAnimationWidget is still playing the idle animation instead of the reaction animation. I know that it's being rebuilt somehow because I can see that there is a slight unnatural discontinuity in the animation when I hit the button (plus the print messages).
Why is setState() not updating the SpriteAnimationWidget with a new animation parameter?
I am relatively new to Flutter and Flame, so I would love some help or advice.
ps. I tried using the same sprite sheet for the change with a different row (instead of using a completely different sprite sheet as in the code above), but the result was the same.
-
spydon over 2 yearsI wonder if this is related to the
playReaction
beingasync
, can you try to make it notasync
, just removing the delayed part and see if it works? -
Andy K over 2 years@spydon Thank you for the comment, but I don't think that's the case. I tried the same code with a SpriteWidget, and it worked. To be exact, when I pressed the button, the app successfully returned a SpriteWidget (which only shows one still frame), waited for one second, then returned the SpriteAnimationWidget it used to show before pressing the button. I don't understand why it won't work when I'm doing the same thing for only SpriteAnimationWidgets with different animations.
-
spydon over 2 yearsThat is very strange! My best suggestion is to join the Flame discord and see if anyone else have experienced this issue. discord.com/invite/pxrBmy4
-