Switching screens still not clear to me in version 8.3

Description

I have read a number of posts and am still not clear on the right way to switch screens.

I am currently getting these messages:
[00:03:16.909,606] lvgl: (196.909, +196909) lv_obj_del: the active screen was deleted (in lv_obj_tree.c line #77)

[00:03:16.910,064] <wrn> lvgl: (196.909, +0)     lv_obj_get_disp: No screen found       (in lv_obj_tree.c line #287)
[00:03:16.910,217] <wrn> lvgl: (196.910, +1)     lv_obj_get_disp: No screen found       (in lv_obj_tree.c line #287)
[00:03:16.910,369] <wrn> lvgl: (196.910, +0)     lv_obj_get_disp: No screen found       (in lv_obj_tree.c line #287)
[00:03:16.910,522] <wrn> lvgl: (196.910, +0)     lv_obj_get_disp: No screen found       (in lv_obj_tree.c line #287)

Occasionally I get errors. I’m not sure if I should declare all the screens and swap them, or recreate them on the fly, or something else. I do see some beautiful screens and transitions with lvgl and wish there was a sample in the Zephyr repository.

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

Zephyr, Nordic branch, nRF52 and nRF53

What LVGL version are you using?

8.3

What do you want to achieve?

I want to have a standard way to switch between screens on a wearable display by swiping from one to the next.

What have you tried so far?

I’ve tried declaring the screens then removing them and re-creating them. I have deleted screens, but sometimes I don’t know the calling screen.

Code to reproduce

This code is based on the lvgl sample in Zephyr.

The code block(s) should be formatted like:


//screens
static  lv_obj_t *scr_home;
static  lv_obj_t *scr_left;

int create_screen_home();
int create_screen_left();

//callback 
static void handle_screen_gesture(lv_dir_t event_code);

static void lv_btn_click_callback_left(lv_event_t *e)
{
	LOG_DBG("Button press left");
	ARG_UNUSED(e);
	lv_obj_del(scr_left);
	create_screen_home();
}

static void on_lvgl_screen_gesture_event_callback(lv_event_t *e)
{
	LOG_DBG("Gesture event detected %d", e->code);
    lv_dir_t  dir;
    lv_event_code_t event = lv_event_get_code(e);
    if (event == LV_EVENT_GESTURE) {
        dir = lv_indev_get_gesture_dir(lv_indev_get_act());
        handle_screen_gesture(dir);
    }
	lv_indev_wait_release(lv_indev_get_act()); // Needed otherwise accidental button press will happen
}

static void handle_screen_gesture(lv_dir_t event_code)
{
        switch (event_code) {
            case LV_DIR_LEFT: {
				LOG_DBG("LEFT gesture detected");
				create_screen_left();
                break;
            }
            case LV_DIR_RIGHT: {
				LOG_DBG("RIGHT gesture detected");
                //watchface_change();
                break;
            }
            case LV_DIR_TOP: {
				LOG_DBG("TOP gesture detected");
				//create_screen_top();
                break;
            }
            case LV_DIR_BOTTOM: {
				LOG_DBG("BOTTOM gesture detected");
      			//create_screen_bottom();
                break;
            }
			
            default:
                LOG_ERR("Not a valid gesture code: %d", event_code);
        }
}

int create_screen_home()
{
	scr_home = lv_obj_create(NULL);
  	lv_scr_load_anim(scr_home, LV_SCR_LOAD_ANIM_NONE, 0, 0, true);

	lv_obj_t *hello_world_label;

	lv_obj_set_style_bg_color(lv_scr_act(), lv_color_black(), LV_PART_MAIN);
	lv_obj_set_style_text_color(lv_scr_act(), lv_color_white(), LV_PART_MAIN);

	hello_world_label = lv_label_create(lv_scr_act());

	lv_label_set_text(hello_world_label, "Test Swipe!");
	lv_obj_align(hello_world_label, LV_ALIGN_CENTER, 0, 0);

	lv_obj_add_event_cb(lv_scr_act(), on_lvgl_screen_gesture_event_callback, LV_EVENT_GESTURE, NULL);

}

int create_screen_left()
{
	scr_left = lv_obj_create(NULL);
	// Used this function as it automatically deletes previous screen.
	// Should work as you did also I think. But have not used lv_scr_load_xxx before
  	lv_scr_load_anim(scr_left, LV_SCR_LOAD_ANIM_NONE, 0, 0, true);

	lv_obj_set_style_bg_color(lv_scr_act(), lv_color_black(), LV_PART_MAIN);
	lv_obj_set_style_text_color(lv_scr_act(), lv_color_white(), LV_PART_MAIN);

	lv_obj_t *label = lv_label_create(lv_scr_act());

	if (IS_ENABLED(CONFIG_LV_Z_POINTER_KSCAN) || IS_ENABLED(CONFIG_LV_Z_POINTER_INPUT)) {
		lv_obj_t *home_button;

		home_button = lv_btn_create(lv_scr_act());
		lv_obj_align(home_button, LV_ALIGN_CENTER, 0, 0);
		lv_obj_add_event_cb(home_button, lv_btn_click_callback_left, LV_EVENT_CLICKED,
						NULL);
		label = lv_label_create(home_button);
	} else {
		label = lv_label_create(lv_scr_act());
	}

	lv_label_set_text(label, "LV_DIR_LEFT (1)");
	lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
	lv_obj_set_style_text_font(label, &lv_font_montserrat_16, LV_PART_MAIN);

	lv_obj_add_event_cb(lv_scr_act(), on_lvgl_screen_gesture_event_callback, LV_EVENT_GESTURE, NULL);

	return 0;
}

call it after all wigites on the sreen created!