弹窗¶
1. 简介¶
弹窗是建立在system(lv_layer_sys())层的独立页面组,由popup_fwk进行管理,与app_fwk相互独立。
弹窗功能通过
APP_POPUP_USED宏使能,配置路径:menuconfig (Top) → Product Applicaiton Config支持优先级配置(数值越大优先级越高)
可配置自动生命周期(自动退出时间)
支持自定义背景色
支持设置不同透明度
2. 注册弹窗¶
2.1 注册内置弹窗¶
POPUP_REGISTER(id, priority, time, ptr_size)
参数说明:
id:弹窗唯一标识符(名称)
priority:优先级,数字越大优先级越高
time:弹窗自动退出时间(毫秒)
ptr_size:弹窗全局内存大小,由框架统一管理
2.2 注册动态弹窗¶
动态弹窗注册步骤:
重新定义POPUP_REGISTER(id, priority, time, ptr_size)宏
指定弹窗类型为POPUP_DYNAMIC
POPUP_REGISTER(id, priority, time, ptr_size)
3. 处理弹窗消息¶
POPUP_MSG_HANDLER 中popup_msg_t 类型如下
消息类型 |
触发时机 |
核心用途与处理要点 |
|---|---|---|
|
弹窗启动时 |
可进行数据初始化及背景页面创建,此消息仅接收一次 |
|
弹窗激活时 |
仅在弹窗处于暂停( |
|
弹窗暂停时 |
仅在弹窗处于启动、激活或重新刷新状态时可被调用,用于暂停弹窗的运行 |
|
弹窗刷新时 |
当收到重复的弹窗消息时被调用,用于更新弹窗内容 |
|
弹窗销毁时 |
需释放用户申请的内存及删除创建的任务,当前屏幕上的对象无需主动删除 |
|
弹窗摧毁时 |
不会立即执行,在应用涉及列表嵌套时设置,将在退出列表循环后执行 |
|
弹窗挂起时 |
触发时不会创建新的弹窗消息,用于临时挂起弹窗 |
4. 弹窗使用流程¶
4.1 注册弹窗¶
/**
* @brief Register a new popup to section.
* @param id popup name.
* @param priority popup priority.
* @param time popup countdown timer.
* @param ptr_size popup global memory size.
*/
#define POPUP_REGISTER(id, priority, time, ptr_size) \
POPUP_MSG_HANDLER; \
SECTION_ITEM_REGISTER(POPUP_SECTION_NAME, static const popup_desc_t app_popup) = \
{ \
.id_str = id, \
.handler = msg_handler, \
.prio = priority, \
.running_time = time, \
.mem_size = ptr_size \
}
#define POPUP_REGISTER_EXT(id, priority, time, ptr_size, val) \
POPUP_REGISTER(id, priority, time, ptr_size)
#if defined(BUILD_DLMODULE) && !defined(BSP_USING_PC_SIMULATOR) //compile as dynamic popup
#undef POPUP_REGISTER_EXT
#undef POPUP_REGISTER
#define POPUP_REGISTER_EXT(id, priority, time, ptr_size, val) \
POPUP_MSG_HANDLER; \
void _popup_init_func_##val(void) \
{ \
LOG_I("%s:%s",__func__, id); \
popup_register_for_app(STRINGIFY(MODULE_NAME), id, priority, time, msg_handler, ptr_size, POPUP_DYNAMIC); \
}
#define POPUP_REGISTER(id, priority, time, ptr_size) \
POPUP_REGISTER_EXT(id, priority, time, ptr_size, 0)
#endif
4.2 运行弹窗¶
使用以下接口运行已注册的弹窗:
popup_run(const char *id, void *user_data)
参数说明:
id:弹窗名称(注册时指定的 id)
user_data:自定义数据,可通过POPUP_GET_NODE_PARAM接口在msg_handle中获取
5. 示例:注册一个remind弹窗¶
// 定义弹窗数据结构
typedef struct {
lv_obj_t *bg_page; // 背景页面对象
alarm_node_t *alarm; // 闹钟数据节点
lv_timer_t *timer; // 定时器
void *gif_anim; // GIF动画对象
} popup_alarm_t;
// 全局指针
static popup_alarm_t *p_alarm = NULL;
/**
* 弹窗启动处理函数
* 在弹窗启动时调用,进行初始化操作
*/
static void on_start(void *param)
{
// 获取框架申请的内存
p_alarm = (popup_alarm_t *)POPUP_GET_NODE_MEM_PTR;
RT_ASSERT(p_alarm); // 确保内存获取成功
// 获取背景对象,作为父控件
p_alarm->bg_page = POPUP_GET_NODE_PARENT;
// 获取自定义数据(运行弹窗时传入的数据)
p_alarm->alarm = (alarm_node_t *)POPUP_GET_NODE_PARAM;
// 设置背景属性
lv_ext_set_local_bg_opa(p_alarm->bg_page, LV_OPA_100, LV_PART_MAIN);
lv_ext_set_local_bg(p_alarm->bg_page, LV_COLOR_BLACK, LV_OPA_COVER);
app_screen_lock_enable(false);
// 构建页面内容
popup_alarm_page(p_alarm->bg_page);
}
/**
* 弹窗刷新处理函数
* 当收到重复弹窗消息时调用
*/
static void on_refr(void *param)
{
if (NULL != p_alarm->bg_page)
{
// 更新自定义数据
p_alarm->alarm = (alarm_node_t *)POPUP_GET_NODE_PARAM;
// 停止并释放GIF动画
if (p_alarm->gif_anim)
{
lvsf_gif_anim_pause(p_alarm->gif_anim);
lvsf_gif_anim_deinit(p_alarm->gif_anim);
p_alarm->gif_anim = NULL;
}
// 清除当前页面子对象并重新构建
lv_obj_clean(p_alarm->bg_page);
popup_alarm_page(p_alarm->bg_page);
}
}
/**
* 弹窗销毁处理函数
* 在弹窗即将销毁时调用
*/
static void on_stop(void *param)
{
// 启用屏幕锁定
app_screen_lock_enable(true);
// 清理闹钟相关资源
popup_alarm_delete();
// 全局指针置空,防止悬空引用
p_alarm = NULL;
}
// 注册alarm弹窗
// 优先级:5,自动退出时间:10000ms,内存大小:sizeof(popup_alarm_t)
POPUP_REGISTER("alarm", 5, 10000, sizeof(popup_alarm_t));
具体例程可以参见solution\examples\watch\application\popup\find_phone。