Bootstrap

LVGL如何创建页面并实现页面的切换

如何绘制一个页面

先搞清楚一个问题,那就是绘制一个页面,是直接创建一个新的屏幕,还是基于默认的屏幕创建一个一个的父类呢?

参考这篇文章

LVGL_多界面切换_lvgl 多页面建立-CSDN博客

可知通常是创建一个新的屏幕,每个页面一个新的屏幕。

比如:

注意,如果页面背景比较复杂,比如特定公司的LOGO,用LVGL没法绘制,或者说很难绘制,那就只能直接用图片来作为页面了。通常,背景都不会很复杂,而是很简洁的,复杂的背景会干扰实体的内容,没有人会这么设计的。

创建屏幕时发现一个问题,那就是创建新屏幕,烧录后界面显示白屏;

但是基于默认的活动屏幕可以显示LOGO图片

为啥?

LVGL百问网

找到这样的一段话

显示器只有一个,我们可以把这里的NULL就理解成显示器,就是真实的显示设备。

然后在这个显示器上创建一个屏幕,这里是逻辑屏幕,也就是我们想要的页面。 

但是,创建一个屏幕时,它还不是活动屏幕,必须调用lv_scr_load()函数来激活屏幕,比如:

此时就可以正常显示了。

页面切换

我们可以按照上面的思路来绘制自己想要的页面,但是在此之前,还得了解下另外一个问题,那就是页面的切换。

在lvgl使用的过程中,最初的时候,肯定都会遇到这样的问题,页面之间的切换以及空间的释放。如果不合理的设计的话,一上来就将所有的页面进行初始化,那将会占用许多不必要的内存空间,硬写之间的切换的话,界面一旦多起来,那切换逻辑将会绕来绕去,最终会写不下去。

页面切换时有个要考虑的问题,那就是页面切换时,是否要释放掉原来的页面内存?如果不释放的话,内存占用是不是够用?

那么,如何合理地切换页面呢?

可参考这篇文章:

LVGL学习(3):页面切换原理和页面管理实现_gui guider页面切换-CSDN博客

我们之前已经学过,切换页面有两种方式:一种是绘制所有的页面,然后为他们添加隐藏和显示标志,从而实现页面的切换;还有一种就是切换页面时,先删除前一个页面,再创建新的页面。前者占用大量内存空间,但是可以保留页面信息;后者同一时间只会占用一份内存空间,但是每次进入时数据需要手动重新设置。

隐藏页面切换法?

隐藏页面切换法就是调用以下这两个函数,lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN)和lv_obj_clear_flag(obj, LV_OBJ_FLAG_HIDDEN),来隐藏/显示页面以实现页面的切换。此时,可以指定所有页面有一个共有的父类(通常是一个活动屏幕)。但是如果将所有的页面都建立于一个屏幕上,不仅浪费内存,而且页面之间的管理也非常乱。

所以,我们可以给每个页面分配一个屏幕,然后采用函数lv_scr_load来加载一个屏幕。

有了这个函数,实际上页面切换就很简单了,对于每个页面来说,一个lv_obj_t基础对象表示一个页面,我们只需要让一个页面中所有的组件都以这个页面lv_obj_t为父类即可,然后用lv_scr_load函数进行加载就行了。对于lv_scr_load函数来说,仅支持单个页面的显示,参数是哪个页面,显示的就是哪个页面。并且,显示的屏幕就会变成当前的活动屏幕,可以通过lv_scr_act来获取。

也就是说,如果是隐藏和显示标志,就需要先后调用lv_obj_add_flag和lv_obj_clear_flag来实现切换,如果不隐藏,会对新显示的页面有影响;但是使用lv_scr_load来加载一个屏幕,则不用先隐藏之前的屏幕,因为同一时间只会有一个活动屏幕。这种情况下,就算之前的页面没有被删除,也不会影响新的页面。

此时,我们可以在切换之前,释放之前屏幕上的内存,注意,用的是函数lv_obj_clean,而不是lv_obj_del,因此并不是删除原来的屏幕。当然,也可以选择删除。

总结上面的内容,得出两种常用的切换页面的方式:

1

所有的页面共用一个活动屏幕,然后一起创建出来,接着用隐藏和显示来切换,此时,页面越多,则内存占用越多;

参考这篇文章:

LVGL实现页面切换 - 知乎

2

每个页面单独一个屏幕,然后通过lv_scr_load加载屏幕来切换页面,切换时,可以选择释放之前屏幕的内存,也可以直接一些,删除之前的屏幕对象。这种情况下,每次加载新页面时,都需要重新初始化页面中的组件。

这里基于第二种思路,提供一种初步的切换方案。

这种方案主要分为三个部分。

第一部分:先定义所有的页面对象,并在初始化时创建好所有的屏幕页面,因为后续会释放屏幕的内存空间,但是并不会删除对象,所以初始时就创建好,而且后续操作页面就会基于这些变量进行,从而利用面向对象的思路使得操作更加简便,同时也避免了每次进入页面时都要重新创建一个新的屏幕(这样新建的屏幕的指针可能每次都不一样);

第二部分:基于已经创建好的页面来添加各页面中的组件,也就是将各页面绘制出来,绘制完成之后,别忘了要加载屏幕;

第三部分:实现页面的切换,就是先释放当前的页面内存,然后绘制新的页面;

这里使用枚举来定义了各个页面,是可选的。

总结来说就是:

① 定义和创建页面对象;

② 绘制页面内容;

③ 切换页面。

;