LVGL循环滑动



lv_coord_t get_content_height(lv_obj_t* cont) {
    lv_coord_t h = 0;
    lv_coord_t pad_row = lv_obj_get_style_pad_row(cont, LV_PART_MAIN);
    int total = lv_obj_get_child_cnt(cont);

    for (int i = 0; i < total; i++) {
        h += lv_obj_get_height(lv_obj_get_child(cont, i));
        if (i < total - 1) h += pad_row; // 包含行间距
    }
    return h + lv_obj_get_style_pad_top(cont, LV_PART_MAIN)
        + lv_obj_get_style_pad_bottom(cont, LV_PART_MAIN);
}

/* 增强版滚动事件回调 */
static void my1_scroll_event_cb(lv_event_t * e) {
    static bool is_adjusting = false;
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * cont = lv_event_get_target(e);

    if(code == LV_EVENT_SCROLL && !is_adjusting) {
        is_adjusting = true;
        lv_coord_t scroll_y = lv_obj_get_scroll_y(cont);
        lv_coord_t cont_h = lv_obj_get_height(cont);
        lv_coord_t content_h = get_content_height(cont);

        /* 动态调整阈值(根据实际项目高度计算)*/
        const lv_coord_t item_height = 80; // 每个列表项高度
        const lv_coord_t threshold = 0;// item_height;// *15 / 10;

        /* 向下滚动越界处理 */
        if(scroll_y < -threshold) {
            // 将最底部项移动到顶部
            lv_obj_t * last_child = lv_obj_get_child(cont, lv_obj_get_child_cnt(cont)-1);
            lv_obj_move_to_index(last_child, 0);
            
            // 保持滚动位置连续
            lv_obj_scroll_to_y(cont, scroll_y + item_height, LV_ANIM_OFF);
        }
        /* 向上滚动越界处理 */
        else if(scroll_y > content_h - cont_h + threshold) {
            // 将最顶部项移动到底部
            lv_obj_t * first_child = lv_obj_get_child(cont, 0);
            lv_obj_move_to_index(first_child, lv_obj_get_child_cnt(cont)-1);            
            // 保持滚动位置连续
            lv_obj_scroll_to_y(cont, scroll_y - item_height, LV_ANIM_OFF);
        }

        is_adjusting = false;
    }
}

/* 优化后的列表项添加函数 */
void my1_list_add_item(lv_obj_t * parent, const char* txt)
{
    // 创建列表项容器
    lv_obj_t* item = lv_obj_create(parent);
	//lv_obj_remove_style_all(item); // 清除默认样式
    lv_obj_set_size(item, LV_PCT(100), 80);  // 固定高度80像素
    lv_obj_set_style_bg_color(item, lv_color_hex(lv_rand(0x00, 0xffffff)), 0);
    lv_obj_set_style_radius(item, 12, 0);    // 添加圆角

    // 添加渐变背景
    lv_obj_set_style_bg_grad_dir(item, LV_GRAD_DIR_VER, 0);
    lv_obj_set_style_bg_grad_color(item, lv_color_hex(0x404040), 0);
    lv_obj_set_style_bg_color(item, lv_color_hex(lv_rand(0x444444, 0x888888)), 0);	
    
    // 创建标签(带阴影效果)
    lv_obj_t* txtlabel = lv_label_create(item);
    lv_label_set_text(txtlabel, txt);
    lv_obj_set_style_text_color(txtlabel, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_opa(txtlabel, LV_OPA_100, 0);
    lv_obj_set_style_text_font(txtlabel, &lv_font_montserrat_24, 0);
    lv_obj_align(txtlabel, LV_ALIGN_CENTER, 0, 0);
    
    // 添加阴影效果
    lv_obj_set_style_shadow_width(item, 30, 0);
    lv_obj_set_style_shadow_color(item, lv_color_hex(0x000000), 0);
    lv_obj_set_style_shadow_opa(item, LV_OPA_30, 0);
}

/* 增强型示例函数 */
void demo1_cyclic_list()
{
    // 创建主容器
    lv_obj_t* obj = lv_obj_create(lv_scr_act());
    lv_obj_set_size(obj, LV_PCT(100), LV_PCT(100));
    lv_obj_set_style_bg_color(obj, lv_color_hex(0xF0F0F0), 0);  // 设置背景色
    lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);             // 垂直布局
    //lv_obj_set_flex_align(obj, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);    
    // 添加滚动事件监听
    lv_obj_add_event_cb(obj, my1_scroll_event_cb, LV_EVENT_SCROLL, NULL);
    
    // 设置滚动回弹效果
    //lv_obj_set_scroll_bounce(obj, 30);  // 回弹系数       
    // 添加列表项
    for(int i=0; i<10; i++){
        char buff_txt[10] = {0};
        lv_snprintf(buff_txt, sizeof(buff_txt), "%03d", i);
        my1_list_add_item(obj, buff_txt);
       #if 0 
        // 添加间距(最后一项不加)
        if(i < 9) {
            lv_obj_t* spacer = lv_obj_create(obj);
            lv_obj_set_size(spacer, LV_PCT(100), 10);  // 10像素间距
            lv_obj_remove_style_all(spacer);           // 清除默认样式
        }
	#endif	
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值