How to wait for an animation to finish?


Hello, I want to execute a function after an animation has finished. I am using the Tileview Widget and want to change the color of a tile once I swipe it away. The problem is that once I release the current tile, the animation to show the next tile starts but the color of the “swiped” tile already changes. Is there any event I can receive regarding animations?

Best regards

What MCU/Processor/Board and compiler are you using?

VS-Simulator on Windows

What LVGL version are you using?


What do you want to achieve?

Execute a function when an animation has finished.

What have you tried so far?

Sleep(TheAnimationTime), while(lv_anim_count_running) {;}

There is a lv_anim_ready_cb() thats called when an animation finishes that might be what you are after

You could do it like so

lv_anim_set_ready_cb(&YourAnim, anim_ready_cb);

void anim_ready_cb(lv_anim_t * a) {
//Do whatever you want to do. Like change color

Thanks for hint, that might be it!

But how can I access the animation created by the tileview?

I also thought about creating a task which checks if there are any active animations but it’s the same problem accessing the tileviews animation.

I would’ve to implement something into lv_tileview.c, maybe also create a new event that triggers when the animation finishes.

Yeah, I can see that. Don’t know if there is an easy fix but I’ll be on the lookout. Else you would probably be better off asking @embeddedt, since I´m not well acquainted with all of LVGL, or someone else with more knowledge :smiley:

Thank you :slight_smile: I’m currently working on a task which checks the animation. I’ll post updates here

Maybe something like this could be applicable?
Mind you i haven’t tested this:

lv_obj_t* tileview = lv_tileview_create(screen, NULL); //This is of course just a test object.
lv_anim_t* a  = lv_anim_get(lv_page_get_scrollable(tileview), NULL);
if (a != NULL) {
lv_anim_set_ready_cb(&a, anim_ready_cb);

If you take a look at lv_tileview_set_tile_act in lv_tileview.c here: tileview.c the animation is applied to the object returned from lv_page_get_scrollable(tileview). So my thought was that we get that object (called lv_obj_t* scrl) like in lv_tileview.c and somehow figure out when its created, and call the aboce code which apllies a ready_cb. It´s a bit of a gamble, and there might be better solutions, but I wanted to share the thought :smiley:

Oh man that’s a little high level for me as a beginner. I found that the following works for now:

lv_task_t* task = lv_task_create(waitForAnim, 20, LV_TASK_PRIO_HIGH, NULL);
void waitForAnim(lv_task_t* task)
    if (pageChanged)
        if (lv_anim_count_running() == 0)
            pageChanged = false;


I know this might be a little inefficient but for now it works!

I’ll try to figure out a way to use your approach, because the relevant mechanics are already there and just need to be connected…

Yours look quite good as well, but my only concern regarding it could be that you would end up reacting on a whole other animation that might be running simultaneously, but that might be a bit unlikely i don’t know. Just a thought

1 Like

Yes thats why I added the bool pageChanged so the task only reacts when exactly this animation executes. And for now I don’t think there willl be any other animations in my project.

Hi there!
Anyone still here? I have generated a UI with squareline studio, and struggling with this issue of how to get my startCapture function to run after the countdown animations, as shown here:

void ui_event_captureButton( lv_event_t * e) {
    lv_event_code_t event_code = lv_event_get_code(e);lv_obj_t * target = lv_event_get_target(e);
if ( event_code == LV_EVENT_PRESSED) {
      _ui_screen_change( &ui_cancelScreen, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_cancelScreen_screen_init);
      three_Animation(ui_three, 0);
      two_Animation(ui_two, 0);
      one_Animation(ui_one, 0);
      //startCapture( e );

Any thoughts greatly appreciated!