LVGL可拖拽窗口实现

一、 LVGL拖拽功能

    LVGL obj提供了使能拖拽功能的函数:

lv_obj_set_drag(win, true);

    不过在多元素界面,例如下边在 bg win上创建了若干个 sub win,bg win大部分面积被覆盖的情况下,如果单纯将 bg win 设置为可拖拽,则只有点击到  没有被覆盖的区域才能成功,效果不满足要求;如果简单的把 sub win 也设置为可拖拽,结果是在 bg win中拖拽。       
  

 二、通过回调函数实现功能

     要实现的功能可通过事件触发时候改变 win 位置实现,如下,在初始化弹出窗口时候将占用面积较大的面板都添加回调函数,这样只要点击到这些地方都能成功触发

void uiInit(uint8_t popUpFlag)
{
    //init
    *****

    if(popUpFlag)	
    {
	    lv_obj_set_event_cb(ui->win, homePopUpUIDragEvCb);
	    lv_obj_set_event_cb(ui->sub1.win, homePopUpUIDragEvCb);
	    lv_obj_set_event_cb(ui->sub2.win, homePopUpUIDragEvCb);
	    lv_obj_set_event_cb(ui->sub3.win, homePopUpUIDragEvCb);
    }
}

    在回调函数中在 LV_EVENT_PRESSING 等事件中获取偏移量然后更新 win 位置,优点是还可以限制拖拽边界等一系列操作。

void homePopUpUIDragEvCb(lv_obj_t* obj, lv_event_t e)
{
    if (e == LV_EVENT_PRESSING)
    {
	    lv_indev_t* indev = lv_indev_get_act(); //获取输入设备
	    if (indev == NULL)  return;

	    lv_point_t vect;
	    lv_indev_get_vect(indev, &vect);  //获取输入坐标位移向量

        if( vect.x != 0 || vect.y !=0 )
		{
			lv_coord_t x = lv_obj_get_x(getHomePUUI()->win) +vect.x;
			lv_coord_t y = lv_obj_get_y(getHomePUUI()->win)+ vect.y;
			lv_obj_set_pos(getHomePUUI()->win, (x<0)?0:((x>LV_HOR_RES_MAX-1-150)?(LV_HOR_RES_MAX-1-150):x), (y<0)?0:((y>LV_VER_RES_MAX-1-50)?(LV_VER_RES_MAX-1-50):y));//Limit drag boundaries 
		}
    }
    else if (e == LV_EVENT_PRESS_LOST)
    {
		lv_obj_set_ext_click_area(getHomePUUI()->win, 100, 100, 100, 100); //expand click area when press lost
    }
	else if (e == LV_EVENT_RELEASED)
    {
		lv_obj_set_ext_click_area(getHomePUUI()->win, 0, 0, 0, 0); //expand click area clear when released
    }
}


更新:

        以上实现方式虽然增加了点击面积,但在指针离开 obj容易断触。

        通过学习 lvgl源码 触摸 obj 判定部分,了解到 obj存在 protect 属性,其中一个保护项 LV_PROTECT_PRESS_LOST 为:若 press 后离开 obj区域,但未断触,则不更新 判定obj。

        因此,在配置回调时增加 该属性就可保证拉动不断触

lv_obj_set_event_cb(ui->sub1.win, homePopUpUIDragEvCb);
lv_obj_add_protect(ui->sub1.win, LV_PROTECT_PRESS_LOST);		//when press out of obj, don't change act obj

LVGL可拖拽窗口效果

三、使能拖拽结合回调?

        直接使能拖拽后窗口拖拽可能拖到边边,没法拉回来,通过开启回调,类似 “二" 中设置方式设置可以限制边缘。

        另外有 LV_EVENT_DRAG_BEGIN(拖拽开始时触发)、LV_EVENT_DRAG_END(拖拽结束时触发)、LV_EVENT_DRAG_THROW_BEGIN (带初速度(动量)的拖动动作开始时会触发?) 三个事件,在使能拖拽后才会触发。

        是否存在设置子对象跟随父对象拖拽的功能?     

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
### 回答1: 使用lvgl创建浮动窗口,需要以下步骤: 1. 创建一个主窗口对象。 2. 创建一个按钮对象,当点击该按钮时触发打开浮动窗口的事件。 3. 在按钮的回调函数中,创建一个浮动窗口对象。 4. 在浮动窗口对象中添加需要显示的控件,比如文本标签、按钮等。 5. 在浮动窗口对象中添加关闭按钮,当点击该按钮时关闭浮动窗口。 6. 显示浮动窗口对象。 下面是一个简单的示例代码: ``` // 创建主窗口对象 lv_obj_t * main_win = lv_win_create(lv_scr_act(), NULL); // 创建按钮对象 lv_obj_t * btn_open_float_win = lv_btn_create(main_win, NULL); lv_obj_set_pos(btn_open_float_win, 10, 10); lv_obj_set_size(btn_open_float_win, 100, 50); lv_obj_t * label = lv_label_create(btn_open_float_win, NULL); lv_label_set_text(label, "Open Float Win"); lv_btn_set_action(btn_open_float_win, LV_BTN_ACTION_CLICK, btn_open_float_win_cb); // 按钮回调函数 static void btn_open_float_win_cb(lv_obj_t * btn, lv_event_t event) { if (event == LV_EVENT_CLICKED) { // 创建浮动窗口对象 lv_obj_t * float_win = lv_win_create(lv_scr_act(), NULL); lv_obj_set_size(float_win, 200, 150); lv_obj_set_pos(float_win, 50, 50); // 添加控件到浮动窗口对象 lv_obj_t * label = lv_label_create(float_win, NULL); lv_label_set_text(label, "This is a float win"); lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 10); lv_obj_t * btn_close = lv_btn_create(float_win, NULL); lv_obj_set_size(btn_close, 50, 30); lv_obj_set_pos(btn_close, 75, 100); lv_obj_t * label_close = lv_label_create(btn_close, NULL); lv_label_set_text(label_close, "Close"); lv_btn_set_action(btn_close, LV_BTN_ACTION_CLICK, btn_close_cb); } } // 关闭按钮回调函数 static void btn_close_cb(lv_obj_t * btn, lv_event_t event) { if (event == LV_EVENT_CLICKED) { lv_obj_t * float_win = lv_obj_get_parent(lv_obj_get_parent(btn)); lv_obj_del(float_win); } } ``` 这个示例代码中,创建了一个主窗口对象,以及一个打开浮动窗口的按钮对象。当点击按钮时,会触发回调函数`btn_open_float_win_cb`,该函数中创建了一个浮动窗口对象,并在其中添加了一个文本标签和一个关闭按钮。关闭按钮的回调函数`btn_close_cb`中,删除了浮动窗口对象。 ### 回答2: LVGL是一个用于嵌入式图形用户界面的开源库。浮动窗口是一种常见的UI元素,可以在用户界面中以浮动的形式显示,并且可以移动、调整大小和关闭。 要在LVGL中创建浮动窗口,可以按照以下步骤进行: 1. 创建一个容器对象作为浮动窗口的父容器。可以使用lv_cont_create函数来创建容器。 2. 使用lv_obj_set_size函数设置容器的大小,以确定浮动窗口的初始大小。 3. 使用lv_obj_set_pos函数设置容器的位置,确定浮动窗口在用户界面中的初始位置。可以根据需要将其设置为屏幕中央或其他位置。 4. 使用lv_obj_set_drag函数启用拖动功能,以便用户可以通过触摸或鼠标拖动浮动窗口。可以设置拖动功能的边界范围。 5. 使用lv_obj_set_style函数设置浮动窗口的样式,可以更改背景颜色、边框样式等。 6. 使用lv_obj_set_event_cb函数为浮动窗口添加事件回调函数,以便在窗口关闭或其他操作时执行相应的操作。可以根据需要执行自定义操作或显示其他内容。 需要注意的是,LVGL库的使用有一定的学习曲线,需要了解其API和基本概念。可以参考官方文档、示例代码和社区论坛来深入学习和了解LVGL的浮动窗口的用法和实现方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值