chill-chinese / stroke-order-animator

Stroke order animations and quizzes for Chinese characters in Flutter.
https://chill-chinese.github.io/stroke-order-animator/
BSD 3-Clause "New" or "Revised" License
86 stars 22 forks source link

The UI does not change after the second word is loaded #96

Closed giantss closed 2 weeks ago

giantss commented 2 weeks ago
image

In the figure, the animation of the first character is played and the user finishes drawing. When the second character is loaded using _loadStrokeOrder again, the character in the nine-square grid does not change to the second character (the same logic as the first character). This may not be a bug. How can I switch to the second word normally? Most of the code I use comes from the demo code you provided.

Mr-Pepe commented 2 weeks ago

I don't fully understand what you are trying to achieve. It seems that you want to automatically switch to the second character after the first one finishes animating. But you also mention the user drawing something, so maybe you are talking about quiz mode? If you could provide a minimal example that reproduces your issue, I might be able to help.

You can insert print at different places in your code and verify that it does what you think it does. Does the second stroke order get loaded correctly after the first character finishes? If you have a stateful widget, do you use setState to rebuild the widget tree with the new stroke order?

giantss commented 2 weeks ago

You understand it correctly. I'm sorry that I didn't describe it clearly enough and confused you. What I can confirm is that the second character executes _loadStrokeOrder and calls startAnimation to play the animation, but the content in the 9-grid remains at the previous character. I don't know how to update the content of the grid. The following code is almost the same as the demo.

 Widget buildStrokeOrderAnimation(StrokeOrderAnimationController ctl) {
    return Container(
      constraints: BoxConstraints.loose( Size.square(controller.diagramSize)),
      child: Stack(
        children: [
          CustomPaint(
            size:  Size.square(controller.diagramSize),
            painter: const CusStrokeOrderDiagramBackgroundPainter(),
          ),
          StrokeOrderAnimator(
            ctl,
            size:  Size.square(controller.diagramSize),
          ),
        ],
      ),
    );
  }
Mr-Pepe commented 2 weeks ago

That function doesn't get executed when you want your program to switch to the second character, right? If you add a print("...") before return Container that doesn't get printed for the second character, right?

You need to somehow trigger a rebuild of the widget when you have loaded the stroke order. The example code uses a FutureBuilder for that but any state management solution will work.

giantss commented 2 weeks ago

This function (buildStrokeOrderAnimation) should be executed. I debugged it and found that this function will be executed when the program switches to the second character. In theory, the UI of the second character should have been refreshed, but the UI still looks like the first character.

giantss commented 2 weeks ago

Thank you for helping me analyze the problem. I solved this problem. It was my code problem. I forgot to assign the value of _loadStrokeOrder to animationController the second time.