Only last two screens are displayed

After an experiment, it seems I can do a splash screen without using lv_task_once(3) or lv_async_call(3) @embeddedt .

The LVGL lack of task synchronisation doesn’t affect programs starting with less than three automatic (no user interaction) screen calls, so this works:

int main(void)
{
    // Initialise and configure
    ...
    lv_img_create(lv_scr_act(), NULL);  // Root level object
    lv_img_set_src();  // Cause a splashscreen to appear

    // Begin user interaction, the real application
    lv_obj_t *next_scr = create_screen_2();
    lv_scr_load_anim(next_scr, LV_SCR_LOAD_ANIM_OVER, 250ms, 2000ms, true);

    // The third screen (not shown) appears due to a
    // event, which doesn't lead to the LVGL problem
    // of several screens appearing at the same time.
}

Control flow

The advice given by @embeddedt to implement control flow in button callbacks helps avoid the problems from my declarative (see my Screen 1/2/3/4) approach.