让LVGL的tabview组件的页面可以循环切换(无限切换)

前言

lvgl默认创建出来的tabview是不能在第一个和最后一个页面之间循环切换的。

下面的教大家怎么让tabview的页面可以循环切换,也就是:

  • 当切换到第一个页面的时候可以继续切换到最后一个页面
  • 反过来,当切换到最后一个页面的时候可以继续切换到第一个页面

实现思路

我们先要弄清楚 tabview 由哪些部分组成。
选项卡视图对象可用于组织选项卡中的内容。选项卡视图是从其他小部件构建的:

  • tabview主容器
    • 选项卡按钮
    • 选项卡的容器(页面)

选项卡按钮可以位于选项卡视图的顶部、底部、左侧和右侧,或者隐藏起来。
我们可以通过单击选项卡按钮或在选项卡容器上水平滑切换选项卡。

在这里插入图片描述

也就是当我滑动tabview中的页面(选项卡)的时候实际上是在操作tabview中的选项卡部分

所以我们可以给 tabview 中的页面(选项卡)添加一个事件处理回调函数,来完成页面的循环切换功能。

实现代码

// 为 tabview 中的页面(选项卡)部分添加事件处理回调函数
lv_obj_add_event_cb(lv_tabview_get_content(tabview), scroll_begin_event, LV_EVENT_SCROLL_END, NULL);

// 处理滚动事件,完成页面循环切换(无限切换)
static void scroll_begin_event(lv_event_t * e)
{
    lv_obj_t * cont = lv_event_get_target(e);
    lv_event_code_t code = lv_event_get_code(e);

    lv_obj_t * tv = lv_obj_get_parent(cont);

    if(lv_event_get_code(e) == LV_EVENT_SCROLL_END) {
        lv_tabview_t * tabview = (lv_tabview_t *)tv;

        lv_coord_t s = lv_obj_get_scroll_x(cont);

        lv_point_t p;
        lv_obj_get_scroll_end(cont, &p);

        lv_coord_t w = lv_obj_get_content_width(cont);
        lv_coord_t t;

        if(lv_obj_get_style_base_dir(tv, LV_PART_MAIN) == LV_BASE_DIR_RTL)  t = -(p.x - w / 2) / w;
        else t = (p.x + w / 2) / w;

        if(s < 0) t = tabview->tab_cnt - 1;
        else if((t == (tabview->tab_cnt - 1)) && (s > p.x)) t = 0;

        bool new_tab = false;
        if(t != lv_tabview_get_tab_act(tv)) new_tab = true;
        lv_tabview_set_act(tv, t, LV_ANIM_ON);
    }
}

效果

请添加图片描述

lvgl视频教程

[video(video-usChQxXe-1639108755632)(type-bilibili)(url-bilibili html5 player)(image-https://img-blog.csdnimg.cn/img_convert/18f43eb5b4f86d9c6eb975fa670d4b5c.png)(title-百问网LVGL(v8)系列课程(韦东山·监制) 教程基于lvgl v8.2版本,课程适配多个平台、多款板子)]

百问网LVGL(v8)视频课程(韦东山·监制) 教程基于lvgl v8.2版本,课程适配多个平台、多款板子!视频学习地址:https://www.bilibili.com/video/BV1Ya411r7K2

视频教程配套资料

相关学习资源

V9版本无限循环切换代码:

static void scroll_begin_event(lv_event_t * e)
{
    lv_obj_t * cont = lv_event_get_target(e);
    lv_event_code_t code = lv_event_get_code(e);

    lv_obj_t * tv = lv_obj_get_parent(cont);

    if(lv_event_get_code(e) == LV_EVENT_SCROLL_END) {
        lv_indev_t * indev = lv_indev_active();
        if(indev && lv_indev_get_state(indev) == LV_INDEV_STATE_PRESSED) {
            return;
        }

        int32_t tb_index;
        lv_coord_t s;

        lv_point_t p;
        lv_obj_get_scroll_end(cont, &p);

        if(lv_obj_get_style_flex_flow(lv_tabview_get_tab_bar(tv), 0) != LV_FLEX_FLOW_COLUMN) {
            s = lv_obj_get_scroll_x(cont);

            if(s < 0) tb_index = lv_tabview_get_tab_count(tv) - 1;
            if((tb_index == (lv_tabview_get_tab_count(tv) - 1)) && (s > p.x)) tb_index = 0;
        }
        else {
            s = lv_obj_get_scroll_y(cont);

            if(s < 0) tb_index = lv_tabview_get_tab_count(tv) - 1;
            if((tb_index == (lv_tabview_get_tab_count(tv) - 1)) && (s > p.y)) tb_index = 0;
        }

        bool new_tab = false;
        if(tb_index != (int32_t)lv_tabview_get_tab_active(tv)) new_tab = true;

        /*If not scrolled by an indev set the tab immediately*/
        if(lv_indev_active()) {
            lv_tabview_set_active(tv, tb_index, LV_ANIM_ON);
        }
        else {
            lv_tabview_set_active(tv, tb_index, LV_ANIM_OFF);
        }

        if(new_tab) lv_obj_send_event(tv, LV_EVENT_VALUE_CHANGED, NULL);
    }
}


lv_obj_add_event_cb(lv_tabview_get_content(tabview), scroll_begin_event, LV_EVENT_SCROLL_END, NULL);
1 个赞

可以实现点击Tab选项卡按钮界面跳转么

tab本来就有这个功能吧

tab不是相当于一个带导航栏的文本框么,我可以点击这个导航栏跳转到其他界面么

可以吧,你看官方例子