LVGL 本身会完成:
- 触摸坐标命中检测;
- 判断最上层可点击对象;
- 按下、移动、释放;
- 点击和长按;
- 列表拖动滚动;
- 按钮、开关、滑块状态变化;
- 弹窗遮罩和控件层级处理。
我们只需要做两件事:
- 把触摸芯片坐标送给 LVGL;
- 给按钮注册
LV_EVENT_CLICKED等事件。
触摸驱动
定时调用触摸驱动,判断是否有触摸和当前触摸的坐标
void Touch_Read(uint16_t *x, uint16_t *y)
{
//触摸驱动
}
LVGL输入
LVGL 主动调用 read_cb,把内部 lv_indev_data_t 的地址放进来;回调里把坐标和按下状态写进 data->point / data->state,LVGL 返回后自己读走这些值。
static void touch_read_cb(lv_indev_drv_t *drv,lv_indev_data_t *data)
{
uint16_t x;
uint16_t y;
bool pressed;
(void)drv;
pressed = Touch_Read(&x, &y);
data->point.x = x;
data->point.y = y;
data->state = pressed ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
}
void touch_indev_init(void)
{
static lv_indev_drv_t driver;
lv_indev_drv_init(&driver);
driver.type = LV_INDEV_TYPE_POINTER;
driver.read_cb = touch_read_cb; // lvgl内部定时回调
lv_indev_drv_register(&driver);
}
按钮
lv_obj_t *button = lv_btn_create(parent);
lv_obj_set_pos(button, 20, 60);
lv_obj_set_size(button, 120, 40);
static void button_clicked_cb(lv_event_t *event)
{
/* 执行按钮业务 */
}
lv_obj_add_event_cb(button,button_clicked_cb,LV_EVENT_CLICKED,NULL); //点击事件
当用户触摸 (30, 70) 时,LVGL 会自动:
读取触摸坐标
→ 遍历当前页面对象树
→ 找到坐标下最上层的按钮
→ 发送 LV_EVENT_PRESSED
→ 触摸释放
→ 发送 LV_EVENT_RELEASED
→ 满足点击条件
→ 发送 LV_EVENT_CLICKED
→ button_clicked_cb()
应用层完全不需要写:
if (x >= 20 && x <= 140 &&
y >= 60 && y <= 100) {
/* 用户点了这个按钮 */
}