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 (带初速度(动量)的拖动动作开始时会触发?) 三个事件,在使能拖拽后才会触发。

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

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值