目录一、前言二、实现原理三、顶部下拉载体创建四、界面跟随显示实现五、下拉返回功能六、效果优化完善七、总结八、结尾一、前言我是Hello_Embed上一篇我们成功实现了底部滑动返回的交互效果完成了子界面的关闭操作。本篇我们将实现与之对应的顶部下拉界面这个功能常用于嵌入式设备的快捷设置如音量、亮度调节交互逻辑和滑动返回高度相似我们可以基于现有代码快速开发完成。二、实现原理下拉界面的核心逻辑与滑动返回一致通过检测拖动方向 位移阈值判断用户的有效操作从屏幕顶部向下拖动达到指定位移后触发下拉设置界面显示用于独立的参数配置功能。三、顶部下拉载体创建在原有滑动返回代码的基础上新增顶部拖动载体仿照底部滑动条的事件回调逻辑快速实现拖动检测voidmy_ui_main_init(void){lv_obj_t*obj;lv_obj_t*label;lv_obj_t*img;objlv_obj_create(lv_layer_top());lv_obj_set_size(obj,lv_pct(100),30);lv_obj_set_align(obj,LV_ALIGN_TOP_MID);lv_obj_add_event_cb(obj,top_drag_event_handler,LV_EVENT_PRESSING,NULL);lv_obj_add_event_cb(obj,top_drag_event_handler,LV_EVENT_RELEASED,NULL);lv_obj_set_style_opa(obj,LV_OPA_100,0);objlv_obj_create(lv_layer_top());lv_obj_set_size(obj,lv_pct(100),30);lv_obj_set_align(obj,LV_ALIGN_BOTTOM_MID);lv_obj_add_event_cb(obj,drag_event_handler,LV_EVENT_PRESSING,NULL);lv_obj_add_event_cb(obj,drag_event_handler,LV_EVENT_RELEASED,NULL);lv_obj_set_style_opa(obj,LV_OPA_10,0);labellv_label_create(obj);lv_label_set_text(label,Drag me);lv_obj_center(label);g_page_contlv_button_create(lv_screen_active());lv_obj_set_size(g_page_cont,lv_pct(100),lv_pct(100));lv_obj_set_style_bg_color(g_page_cont,lv_color_hex(0x00ff00),0);for(uint16_tindex0;indexLIST_NUM;index){imglv_image_create(g_page_cont);lv_obj_add_flag(img,LV_OBJ_FLAG_CLICKABLE);lv_image_set_src(img,img_cogwheel_argb);lv_obj_set_user_data(img,g_page_list[index]);lv_obj_align(img,LV_ALIGN_TOP_MID,index*100,20);labellv_label_create(img);lv_label_set_text_fmt(label,Page[%d],index1);lv_obj_center(label);lv_obj_add_event_cb(img,event_handler,LV_EVENT_CLICKED,label);}}staticvoidtop_drag_event_handler(lv_event_t*e){lv_obj_t*objlv_event_get_target(e);lv_event_code_tcodelv_event_get_code(e);lv_indev_t*indevlv_indev_active();if(indevNULL)return;lv_point_tvect;lv_indev_get_vect(indev,vect);if(codeLV_EVENT_PRESSING){int32_tylv_obj_get_y_aligned(obj)vect.y;lv_obj_set_y(obj,y);}elseif(codeLV_EVENT_RELEASED){int32_tylv_obj_get_y_aligned(obj);if(y120){LV_LOG_USER(drop page show);}lv_obj_set_y(obj,0);}}四、界面跟随显示实现实现核心效果下拉时界面跟随拖动条同步显示达到阈值后全屏展示。创建全屏容器初始位置隐藏在屏幕外拖动时同步更新容器坐标实现跟随效果达到位移阈值后容器全屏显示。创建隐藏的下拉界面lv_obj_t*drop_down_page_contlv_obj_create(lv_layer_top());lv_obj_set_size(drop_down_page_cont,lv_pct(100),lv_pct(100));lv_obj_center(drop_down_page_cont);lv_obj_set_y(drop_down_page_cont,-(lv_display_get_vertical_resolution(NULL)));完善拖动回调实现界面跟随与阈值触发staticvoidtop_drag_event_handler(lv_event_t*e){lv_obj_t*objlv_event_get_target(e);lv_event_code_tcodelv_event_get_code(e);lv_obj_t*drop_down_page_contlv_event_get_user_data(e);lv_indev_t*indevlv_indev_active();if(indevNULL)return;lv_point_tvect;lv_indev_get_vect(indev,vect);if(codeLV_EVENT_PRESSING){int32_tylv_obj_get_y_aligned(obj)vect.y;lv_obj_set_y(obj,y);lv_obj_set_y(drop_down_page_cont,y-480);}elseif(codeLV_EVENT_RELEASED){int32_tylv_obj_get_y_aligned(obj);if(y120){LV_LOG_USER(drop page show);lv_obj_set_y(drop_down_page_cont,0);}lv_obj_set_y(obj,0);}}代码参数说明obj顶部可拖动的交互条drop_down_page_cont全屏下拉设置界面若需要隐藏拖动边框可将载体不透明度设为 0lv_obj_set_style_opa(obj,LV_OPA_0,0);五、下拉返回功能实现点击空白处关闭下拉界面的功能绑定点击事件将界面复位到屏幕外lv_obj_add_event_cb(drop_down_page_cont,drag_down_page_cont_event_handler,LV_EVENT_CLICKED,NULL);点击事件回调staticvoiddrag_down_page_cont_event_handler(lv_event_t*e){lv_obj_t*objlv_event_get_target(e);lv_obj_set_y(obj,-(lv_display_get_vertical_resolution(NULL)));}六、效果优化完善为了更贴近手机交互设置下拉界面半透明效果下拉时仍能看到主界面lv_obj_set_style_bg_opa(drop_down_page_cont,LV_OPA_80,0);最终优化效果七、总结下拉界面基于位移阈值检测实现逻辑复用滑动返回代码开发效率高屏幕外隐藏容器 同步拖动坐标实现流畅的跟随显示效果点击空白复位 半透明背景完美模拟手机端下拉快捷面板适配嵌入式设备音量、亮度等快捷设置场景。八、结尾我们已经完成了滑动返回、下拉界面两大核心交互功能嵌入式 UI 的体验已经无限接近移动端。我是Hello_Embed后续我们会继续完善界面的功能与视觉效果打造更专业的嵌入式交互系统期待你的关注