当基础对象被创建出来后,它默认是一个圆角矩阵,如下图所示:
在设计较为复杂的 GUI 界面时,不同功能的模块之间需要清晰地划分区域,此时,我们可以使用基础对象作为背景,对不同的区域进行划分。
当 GUI 界面中有一些组成内容相似的模块时,可以利用基础对象作为父对象,创建出其他的部件,这些部件将出现在基础对象内部,此时,我们只需要管理各基础对象之间的布局即可,其他的部件会随之变化。辅助布局的示意图如下:
当基础对象做为父对象,创建出其他的部件时,这些被创建出来的部件将出现在其父对象的内部,换言之,此时的基础对象就是一个容器,它里面子对象会随之移动。在 UI 设计中,我们可以利用上述的特性,实现界面的切换,示意图如下所示:
由上图可知,基础对象 1、2 分别用于管理界面 1、2,它们之中存在一些子对象(例如开关),当用户需要切换界面时,只需切换容器即可。
接下来,我们介绍界面切换的两种实现方法:
方法一:删除法。当用户删除一个父对象时,它所有的子对象也会被一并删除,因此,我们需要实现界面的切换,可以调用 lv_obj_del 函数,直接删除基础对象(父对象),然后再创建新的界面,这样即可实现界面切换,示意图如下所示:
方法二:隐蔽法。此方法的原理和删除法类似,只不过这里是将界面隐藏起来,需要的时候还能还原。注意:隐藏的界面并未被删除,其占用内存也没有得到释放,因此,当用户使用此方法切换界面时,需要考虑内存溢出的隐患。隐蔽法的示意图如下所示:
由上图可知,隐藏法的实现逻辑如下:先创建出不同的界面,然后调用 lv_obj_add_flag 函数,为指定的界面添加隐藏的标志,此时,该界面将隐藏,而当我们需要显示某个界面时,只需要调用 lv_obj_clear_flag 函数,清除隐藏属性即可。注意:不要同时清除多个界面的隐藏属性,否则可能出现显示混乱的问题。
设置一个或多个标志,其函数原型如下所示:
void lv_obj_add_flag(lv_obj_t *obj, lv_obj_flag_t f);
该函数的形参,如下表所示:
参数 | 描述 |
---|---|
obj | 指向对象的指针 |
f | 标志相关枚举 |
清除一个或多个标志,其函数原型如下所示:
void lv_obj_clear_flag(lv_obj_t *obj, lv_obj_flag_t f);
该函数的形参,如下表所示:
参数 | 描述 |
---|---|
obj | 指向对象的指针 |
f | 标志相关枚举 |
在 LVGL 中,标志相关的枚举如下源码所示:
typedef enum {
LV_OBJ_FLAG_HIDDEN = (1L << 0), /*隐藏*< Make the object hidden. (Like it wasn't there at all) */
LV_OBJ_FLAG_CLICKABLE = (1L << 1), /**< Make the object clickable by the input devices*/
LV_OBJ_FLAG_CLICK_FOCUSABLE = (1L << 2), /**< Add focused state to the object when clicked*/
LV_OBJ_FLAG_CHECKABLE = (1L << 3), /**< Toggle checked state when the object is clicked*/
LV_OBJ_FLAG_SCROLLABLE = (1L << 4), /**< Make the object scrollable*/
LV_OBJ_FLAG_SCROLL_ELASTIC = (1L << 5), /**< Allow scrolling inside but with slower speed*/
LV_OBJ_FLAG_SCROLL_MOMENTUM = (1L << 6), /**< Make the object scroll further when "thrown"*/
LV_OBJ_FLAG_SCROLL_ONE = (1L << 7), /**< Allow scrolling only one snappable children*/
LV_OBJ_FLAG_SCROLL_CHAIN_HOR = (1L << 8), /**< Allow propagating the horizontal scroll to a parent*/
LV_OBJ_FLAG_SCROLL_CHAIN_VER = (1L << 9), /**< Allow propagating the vertical scroll to a parent*/
LV_OBJ_FLAG_SCROLL_CHAIN = (LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER),
LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1L << 10), /**< Automatically scroll object to make it visible when focused*/
LV_OBJ_FLAG_SCROLL_WITH_ARROW = (1L << 11), /**< Allow scrolling the focused object with arrow keys*/
LV_OBJ_FLAG_SNAPPABLE = (1L << 12), /**< If scroll snap is enabled on the parent it can snap to this object*/
LV_OBJ_FLAG_PRESS_LOCK = (1L << 13), /**< Keep the object pressed even if the press slid from the object*/
LV_OBJ_FLAG_EVENT_BUBBLE = (1L << 14), /**< Propagate the events to the parent too*/
LV_OBJ_FLAG_GESTURE_BUBBLE = (1L << 15), /**< Propagate the gestures to the parent*/
LV_OBJ_FLAG_ADV_HITTEST = (1L << 16), /**< Allow performing more accurate hit (click) test. E. g. consider rounded corners.*/
LV_OBJ_FLAG_IGNORE_LAYOUT = (1L << 17), /**< Make the object position-able by the layouts*/
LV_OBJ_FLAG_FLOATING = (1L << 18), /**< Do not scroll the object when the parent scrolls and ignore layout*/
LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS = (1L << 19), /**< Send `LV_EVENT_DRAW_TASK_ADDED` events*/
LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 20),/**< Do not clip the children to the parent's ext draw size*/
#if LV_USE_FLEX
LV_OBJ_FLAG_FLEX_IN_NEW_TRACK = (1L << 21), /**< Start a new flex track on this item*/
#endif
LV_OBJ_FLAG_LAYOUT_1 = (1L << 23), /**< Custom flag, free to use by layouts*/
LV_OBJ_FLAG_LAYOUT_2 = (1L << 24), /**< Custom flag, free to use by layouts*/
LV_OBJ_FLAG_WIDGET_1 = (1L << 25), /**< Custom flag, free to use by widget*/
LV_OBJ_FLAG_WIDGET_2 = (1L << 26), /**< Custom flag, free to use by widget*/
LV_OBJ_FLAG_USER_1 = (1L << 27), /**< Custom flag, free to use by user*/
LV_OBJ_FLAG_USER_2 = (1L << 28), /**< Custom flag, free to use by user*/
LV_OBJ_FLAG_USER_3 = (1L << 29), /**< Custom flag, free to use by user*/
LV_OBJ_FLAG_USER_4 = (1L << 30), /**< Custom flag, free to use by user*/
} _lv_obj_flag_t;
void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t size);
参数 | 描述 |
---|---|
obj | 指向对象的指针 |
size | 设置点击区域大小 |
函数 | 描述 |
---|---|
lv_obj_create () | 创建基础对象(矩形) |
lv_obj_set_user_data() | 设置对象的 user_data 字段 |
lv_obj_has_flag() | 检查是否在对象上设置了指定的标志 |
lv_obj_has_flag_any() | 检查是否在对象上设置了任何标志 |
lv_obj_get_state() | 获取对象的状态 |
lv_obj_has_state() | 检查对象是否处于指定状态 |
lv_obj_get_group() | 获取对象的组 |
lv_obj_get_user_data() | 获取对象的用户数据 |
lv_obj_allocate_spec_attr() | 为对象分配特殊数据(还未分配时) |
lv_obj_check_type() | 检查 obj 的类型 |
lv_obj_has_class() | 检查是否有任何对象具有指定的类 |
lv_obj_get_class() | 获取对象的类 |
lv_obj_is_valid() | 检查是否有任何对象在活动 |
创建一个父对象,其宽和高都是屏幕的 2/3,顶部居中,背景色:浅蓝色,代码如下:
/* 获取当前显示屏幕的宽和高 */
int32_t with = lv_obj_get_width(lv_scr_act());
int32_t height = lv_obj_get_height(lv_scr_act());
/* 创建一个父对象 */
parent_obj = lv_obj_create(lv_scr_act());
/* 设置父对象的大小 - 宽和高都是屏幕的 2/3 */
lv_obj_set_size(parent_obj, with*2/3, height*2/3);
/* 设置父对象的位置 - 顶部居中 */
lv_obj_align(parent_obj, LV_ALIGN_TOP_MID, 0, 0);
/* 设置父对象的背景色:浅蓝色 */
lv_obj_set_style_bg_color(parent_obj, lv_color_hex(0x99ccff), 0);
再创建一个子对象,其宽和高都是屏幕的 1/3,居中,背景色:深蓝色,代码如下:
/* 创建一个子对象 */
child_obj = lv_obj_create(parent_obj);
/* 设置子对象的大小 - 宽和高都是父对象的 1/3 */
lv_obj_set_size(child_obj, with/3, height/3);
/* 设置子对象的位置 - 居中 */
lv_obj_align(child_obj, LV_ALIGN_CENTER, 0, 0);
/* 设置子对象的背景色:深蓝色 */
lv_obj_set_style_bg_color(child_obj, lv_color_hex(0x003366), 0);
为父对象添加事件:长按触发,切换父对象背景颜色为绿色;为子对象添加事件,按下触发,重新设置子对象的位置:右侧居中,再向 X 轴偏移 100。代码实现如下:
/* 为父对象添加事件:长按触发 */
lv_obj_add_event_cb(parent_obj, obj_event_cb, LV_EVENT_LONG_PRESSED, NULL);
/* 为子对象添加事件:按下触发 */
lv_obj_add_event_cb(child_obj, obj_event_cb, LV_EVENT_CLICKED, NULL);
void obj_event_cb(lv_event_t * e)
{
lv_obj_t* target = lv_event_get_target(e); /* 获取事件触发源 */
{
if (target == parent_obj) /* 判断触发源:是不是父对象? */
{
/* 设置父对象的背景色:绿色 */
lv_obj_set_style_bg_color(parent_obj, lv_color_hex(0x00FF00), 0);
}
else if (target == child_obj) /* 判断触发源:是不是子对象? */
{
/* 重新设置子对象的位置:右侧居中,再向 X 轴偏移 100 */
lv_obj_align(child_obj, LV_ALIGN_RIGHT_MID, 100, 0);
}
}
}
完整代码见:Demo_lv_obj.c
把工程编译并下载到开发板中,运行效果如下图所示:
当点击子对象时,则重新设置子对象的位置,使其右侧居中,并且向 X 轴的正半轴偏移 100 像素,此时,子对象超出父对象的部分默认不可见。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。