《lvgl基础学习 —— 页面切换》

1.页面切换

  Screen(屏幕)是 LVGL 中的“页面根节点”

  • 每个 screen 是一个 独立的 UI 树

  • 同一时间 只有一个 screen 是激活显示的

Screen A (Home)
Screen B (Settings)
Screen C (Info)

  页面切换 = 切换当前激活的screen

Screen的本质:

lv_obj_t *screen = lv_obj_create(NULL);

注意这点:

  • parent = NULL

  • 说明它是“顶级对象”

  screen 不是普通 container

页面切换的基础API

创建screen:

lv_obj_t *scr = lv_obj_create(NULL);

加载screen(切换页面):

lv_scr_load(scr);

  瞬间切换,无动画。

 

demo:两个页面 + 按钮切换

定义两个screen(全局或static)

static lv_obj_t *scr_home;
static lv_obj_t *scr_settings;

创建Home界面

static void goto_settings_cb(lv_event_t *e)
{
    lv_scr_load(scr_settings);
}

void create_home_screen(void)
{
    scr_home = lv_obj_create(NULL);

    lv_obj_t *label = lv_label_create(scr_home);
    lv_label_set_text(label, "Home Screen");
    lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 20);

    lv_obj_t *btn = lv_btn_create(scr_home);
    lv_obj_center(btn);
    lv_obj_add_event_cb(btn, goto_settings_cb,
                        LV_EVENT_CLICKED, NULL);

    lv_obj_t *btn_label = lv_label_create(btn);
    lv_label_set_text(btn_label, "Go Settings");
    lv_obj_center(btn_label);
}

创建setting界面

static void goto_home_cb(lv_event_t *e)
{
    lv_scr_load(scr_home);
}

void create_settings_screen(void)
{
    scr_settings = lv_obj_create(NULL);

    lv_obj_t *label = lv_label_create(scr_settings);
    lv_label_set_text(label, "Settings Screen");
    lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 20);

    lv_obj_t *btn = lv_btn_create(scr_settings);
    lv_obj_center(btn);
    lv_obj_add_event_cb(btn, goto_home_cb,
                        LV_EVENT_CLICKED, NULL);

    lv_obj_t *btn_label = lv_label_create(btn);
    lv_label_set_text(btn_label, "Back Home");
    lv_obj_center(btn_label);
}

main() 里初始化并加载首页

create_home_screen();
create_settings_screen();

lv_scr_load(scr_home);

 

带动画的切换:

lv_scr_load_anim(scr,
    LV_SCR_LOAD_ANIM_MOVE_LEFT,
    300,    // 动画时间 ms
    0,      // 延迟
    false   // 是否自动删除旧 screen
);

常用动画类型:

| 动画           | 说明  |
| ------------- | ---   |
| `MOVE_LEFT`   | 向左滑 |
| `MOVE_RIGHT`  | 向右滑 |
| `MOVE_TOP`    | 向上   |
| `MOVE_BOTTOM` | 向下   |
| `FADE_ON`     | 渐显   |

从Home->Settings(左滑)

lv_scr_load_anim(scr_settings,
    LV_SCR_LOAD_ANIM_MOVE_LEFT,
    300, 0, false);

从Settings->Home(右滑)

lv_scr_load_anim(scr_home,
    LV_SCR_LOAD_ANIM_MOVE_RIGHT,
    300, 0, false);

 

是否要“删除旧页面“:

  参数解释(第 5 个参数):auto_del

  • true:切换后 自动删除旧 screen

  • false:保留旧 screen

推荐策略:

页面类型               建议
Home / 主页面         false
设置页                false
临时页面(弹窗型)      true

  常驻页面不要频繁创建/销毁。

 

demo:主页 -> 设置,带动画

static lv_obj_t *scr_home;
static lv_obj_t *scr_settings;

static void goto_settings_cb(lv_event_t *e)
{
    lv_scr_load_anim(scr_settings,
        LV_SCR_LOAD_ANIM_MOVE_LEFT,
        300, 0, false);
}

static void goto_home_cb(lv_event_t *e)
{
    lv_scr_load_anim(scr_home,
        LV_SCR_LOAD_ANIM_MOVE_RIGHT,
        300, 0, false);
}

void ui_screens_init(void)
{
    /* Home */
    scr_home = lv_obj_create(NULL);
    lv_obj_t *h_label = lv_label_create(scr_home);
    lv_label_set_text(h_label, "Home");
    lv_obj_align(h_label, LV_ALIGN_TOP_MID, 0, 20);

    lv_obj_t *h_btn = lv_btn_create(scr_home);
    lv_obj_center(h_btn);
    lv_obj_add_event_cb(h_btn, goto_settings_cb,
                        LV_EVENT_CLICKED, NULL);
    lv_obj_t *h_btn_label = lv_label_create(h_btn);
    lv_label_set_text(h_btn_label, "Settings");
    lv_obj_center(h_btn_label);

    /* Settings */
    scr_settings = lv_obj_create(NULL);
    lv_obj_t *s_label = lv_label_create(scr_settings);
    lv_label_set_text(s_label, "Settings");
    lv_obj_align(s_label, LV_ALIGN_TOP_MID, 0, 20);

    lv_obj_t *s_btn = lv_btn_create(scr_settings);
    lv_obj_center(s_btn);
    lv_obj_add_event_cb(s_btn, goto_home_cb,
                        LV_EVENT_CLICKED, NULL);
    lv_obj_t *s_btn_label = lv_label_create(s_btn);
    lv_label_set_text(s_btn_label, "Back");
    lv_obj_center(s_btn_label);

    lv_scr_load(scr_home);
}

 

工程级页面管理建议:

ui/
├── ui_home.c
├── ui_settings.c
├── ui_about.c
└── ui_screens.c   ← 统一管理 screen

不推荐

❌ 在回调里 lv_obj_create(NULL)
❌ 页面切换时频繁 malloc/free
❌ 把所有页面写在一个 .c 里

 

常见坑(一定要看)

❌ 1️⃣ 把 screen 当 container 用
→ parent 必须是 NULL

❌ 2️⃣ 切换后再创建 UI
→ 会看到白屏闪烁

❌ 3️⃣ auto_del 用错
→ 页面丢失 / 崩溃

❌ 4️⃣ 在非 LVGL 线程切换 screen
→ 必炸(LVGL 非线程安全)

 

 

 

 

posted @ 2025-12-19 16:54  一个不知道干嘛的小萌新  阅读(0)  评论(0)    收藏  举报