Best practice to know when lv_animimg animation is complete?

Important: unclear posts may not receive useful answers.

Description

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

nrf528

What LVGL version are you using?

8.2 (not able to use master with my project as it is tied to the nrf zephyr-sdk

What do you want to achieve?

I want to be able to take actions an animation has repeated x number of times

What have you tried so far?

I have tried to use the lv_anim_set_ready_cb callback but I am unable to figure out how to pass in the first param of type lv_anim_t * since my object is of type lv_animimg_t. I am also unsure what the param type for the callback arguments should be?

Code to reproduce

void animation_completed_cb( **????** )
{
	LOG_INF("Animation complete");
}

main(){
    lv_obj_t *x_anim = lv_animimg_create( x_anim_screen );
    lv_obj_center( x_anim );
    lv_animimg_set_src( x_anim, (const void **)x_imgs, 9 );
    lv_animimg_set_duration( x_anim, 4000 );
    lv_animimg_set_repeat_count( x_anim, 1 );
    lv_anim_set_ready_cb( **????**, animation_completed_cb );
    lv_animimg_start( x_anim );
    while( 1 )
    {
        k_msleep( lv_task_handler() );
    }
}

Update:

I decided to move away from lv_animimg and instead use lv_anim

LV_IMG_DECLARE( x_1 )
LV_IMG_DECLARE( x_2 )
LV_IMG_DECLARE( x_3 )
LV_IMG_DECLARE( x_4 )
LV_IMG_DECLARE( x_5 )
LV_IMG_DECLARE( x_6 )
LV_IMG_DECLARE( x_7 )
LV_IMG_DECLARE( x_8 )
LV_IMG_DECLARE( x_9 )
LV_IMG_DECLARE( logo );
static const lv_img_dsc_t *x_imgs[9] = { &x_1, &x_2, &x_3, &x_4, &x_5, &x_6, &x_7, &x_8, &x_9 };

static void x_anim_set_img_src( void *obj, int32_t v )
{
    lv_img_set_src( obj, x_imgs[v] );
}
main(){
    lv_obj_t *x_anim_img_src = lv_img_create( x_anim_screen );
    lv_obj_center( x_anim_img_src );

    lv_anim_t x_anim;
    lv_anim_init( &x_anim );
    lv_anim_set_exec_cb( &x_anim, x_anim_set_img_src );
    lv_anim_set_var( &x_anim, x_anim_img_src );
    lv_anim_set_time( &x_anim, 5000 );
    lv_anim_set_repeat_count( &x_anim, 2 );
    lv_anim_set_repeat_delay( &x_anim, 1000 );
    lv_anim_set_values( &x_anim, 0, 8 );
    lv_anim_start( &x_anim );
}

I still cant figure out what params to pass in when calling lv_anim_set_ready_cb()

To re-iterate, my call is to know when the animation has completed.

I tried adding the callback but with no luck… it wont trigger

static void x_anim_set_img_src( void *obj, int32_t v )
{
    lv_img_set_src( obj, nfc_imgs[v] );
}

static void anim_set_ready_cb( lv_anim_t * )
{
    LOG_INF( "animation completed" );
}
main {    
	lv_obj_t *x_anim_screen = lv_obj_create( NULL );
    LV_IMG_DECLARE( batteryicon );
    lv_obj_t *batt_img = lv_img_create( x_anim_screen );
    lv_img_set_src( batt_img, &batteryicon );
    lv_obj_align( batt_img, LV_ALIGN_TOP_MID, 0, 0 );
    lv_task_handler();
    k_msleep( 1000 );

    lv_obj_t *x_anim_img_src = lv_img_create( x_anim_screen );
    lv_obj_center( x_anim_img_src );

    lv_anim_t x_anim;
    lv_anim_init( &x_anim );
    lv_anim_set_exec_cb( &x_anim, x_anim_set_img_src );
    lv_anim_set_var( &x_anim, x_anim_img_src );
    lv_anim_set_time( &x_anim, 5000 );
    lv_anim_set_repeat_count( &x_anim, 2 );
    lv_anim_set_repeat_delay( &x_anim, 1000 );
    lv_anim_set_values( &x_anim, 0, 8 );
    lv_anim_start( &x_anim );
    lv_anim_set_ready_cb( &x_anim, anim_set_ready_cb );

    lv_scr_load( x_anim_screen );

    k_mutex_unlock( &lvgl_mutex );
    LOG_INF( "Display init success" );

    while( RUN_FOREVER )
    {
        if( lvgl_render_enable )
        {
            k_mutex_lock( &lvgl_mutex, K_FOREVER );
            const int64_t next_update_in_ms = lv_task_handler();
            k_mutex_unlock( &lvgl_mutex );
            k_sleep( K_MSEC( next_update_in_ms ) );
        }
    }
}

It seems my issue was simply setting the callback after starting the animation. Calling lv_anim_set_ready_cb() before setting lv_anim_start() fixed the issue

1 Like