LVGL 7.11 tileview界面循环切换

定义变量


static const lv_point_t valid_pos2[] = { {0, 0}, {0, 1} ,{0,2},{0,3},{0,4}, {1,2} ,{2,2},{3,2} };
static int delay_cnt;
static int  last_hor_pos;
#define VALID_POS_LEN  sizeof(valid_pos2)/sizeof(valid_pos2[0])
typedef lv_obj_t* (*tileview_elem)(lv_obj_t* scr);



lv_obj_t* create_tileview_elem_00_03(lv_obj_t* scr)
{
	
	lv_obj_t* btn = lv_btn_create(scr, NULL);
	lv_obj_align(btn, scr, LV_ALIGN_CENTER, 0, 0);
	lv_obj_t* label = lv_label_create(btn, NULL);
	lv_label_set_text_fmt(label, "Button 0_3");

	return btn;
}

lv_obj_t* create_tileview_elem_0_1(lv_obj_t* scr)
{
	lv_obj_t* btn = lv_btn_create(scr, NULL);
	lv_obj_align(btn, scr, LV_ALIGN_CENTER, 0, 0);
	lv_obj_t* label = lv_label_create(btn, NULL);
	lv_label_set_text_fmt(label, "Button 0_1");
	return btn;
}

lv_obj_t* create_tileview_elem_0_2(lv_obj_t* scr)
{
	lv_obj_t* btn = lv_btn_create(scr, NULL);
	lv_obj_align(btn, scr, LV_ALIGN_CENTER, 0, 0);
	lv_obj_t* label = lv_label_create(btn, NULL);
	lv_label_set_text_fmt(label, "Button 0_2");
	return btn;
}

lv_obj_t* create_tileview_elem_0_3(lv_obj_t* scr)
{
	lv_obj_t* btn = lv_btn_create(scr, NULL);
	lv_obj_align(btn, scr, LV_ALIGN_CENTER, 0, 0);
	lv_obj_t* label = lv_label_create(btn, NULL);
	lv_label_set_text_fmt(label, "Button 0_3");
	return btn;
}

lv_obj_t* create_tileview_elem_04_01(lv_obj_t* scr)
{
	lv_obj_t* btn = lv_btn_create(scr, NULL);
	lv_obj_align(btn, scr, LV_ALIGN_CENTER, 0, 0);
	lv_obj_t* label = lv_label_create(btn, NULL);
	lv_label_set_text_fmt(label, "Button 0_1");
	return btn;
}

lv_obj_t* create_tileview_elem_1_2(lv_obj_t* scr)
{
	lv_obj_t* btn = lv_btn_create(scr, NULL);
	lv_obj_align(btn, scr, LV_ALIGN_CENTER, 0, 0);
	lv_obj_t* label = lv_label_create(btn, NULL);
	lv_label_set_text_fmt(label, "Button 1_2");
	return btn;
}

lv_obj_t* create_tileview_elem_2_2(lv_obj_t* scr)
{
	lv_obj_t* btn = lv_btn_create(scr, NULL);
	lv_obj_align(btn, scr, LV_ALIGN_CENTER, 0, 0);
	lv_obj_t* label = lv_label_create(btn, NULL);
	lv_label_set_text_fmt(label, "Button 2_2");
	return btn;
}

lv_obj_t* create_tileview_elem_3_2(lv_obj_t* scr)
{
	lv_obj_t* btn = lv_btn_create(scr, NULL);
	lv_obj_align(btn, scr, LV_ALIGN_CENTER, 0, 0);
	lv_obj_t* label = lv_label_create(btn, NULL);
	lv_label_set_text_fmt(label, "Button 3_2");
	return btn;
}

const tileview_elem s_tileview[VALID_POS_LEN] = {
		create_tileview_elem_00_03,
		create_tileview_elem_0_1,
		create_tileview_elem_0_2,
		create_tileview_elem_0_3,
		create_tileview_elem_04_01,
		create_tileview_elem_1_2,
		create_tileview_elem_2_2,
		create_tileview_elem_3_2,
};

定时器回调函数

static void page_task(struct _lv_task_t* task)
{

	if (lv_anim_count_running())
		return;
	lv_obj_t *obj = task->user_data;

	if (delay_cnt)
	{
		if (--delay_cnt == 0) {
			lv_coord_t x, y;
			lv_tileview_get_tile_act(obj, &x, &y);
			if (x == 0 && y == 0) {
				lv_tileview_set_tile_act(obj, 0, 3, LV_ANIM_OFF); 
			}
			else
				if (x == 0 && y == last_hor_pos) {
				lv_tileview_set_tile_act(obj, 0, 1, LV_ANIM_OFF);
			}
	  }
	}
	
}

事件处理回调函数

void btn_handler(struct _lv_obj_t* obj, lv_event_t event)
{
	LV_LOG_USER("--event %d", event);
	if (event == LV_EVENT_PRESSING)
	{
		delay_cnt = 10;
	}
}

创建tileview



lv_obj_t * init_main_tileview(void)
{
	

	lv_obj_t* tv = lv_tileview_create(lv_scr_act(), NULL);
	lv_obj_set_style_local_bg_opa(tv, LV_TILEVIEW_PART_SCROLLBAR, LV_STATE_DEFAULT, LV_OPA_TRANSP);
	lv_obj_set_style_local_bg_opa(tv, LV_TILEVIEW_PART_BG, LV_STATE_DEFAULT, LV_OPA_TRANSP);
	lv_tileview_set_valid_positions(tv, valid_pos2, VALID_POS_LEN);
	lv_tileview_set_edge_flash(tv, true);
	lv_obj_set_size(tv, LV_HOR_RES, LV_VER_RES);
	lv_obj_set_pos(tv, 0, 0);
	last_hor_pos = 0;
	for (int i = 0; i < VALID_POS_LEN; i++)
	{
		if (valid_pos2[i].x == 0)
		{
			if (valid_pos2[i].y > last_hor_pos)
				last_hor_pos = valid_pos2[i].y;
			
		}
	}

	LV_LOG_USER("--last_hor_pos %d", last_hor_pos);
	
	for (int i = 0; i < VALID_POS_LEN; i++) {
		
		lv_obj_t* cont = s_tileview[i](tv);
		lv_obj_set_size(cont, LV_HOR_RES, LV_HOR_RES);
		lv_obj_set_pos(cont, valid_pos2[i].x* LV_HOR_RES, valid_pos2[i].y* LV_HOR_RES);
		lv_tileview_add_element(tv, cont);
		if (i == 1 || i == last_hor_pos-1)
		{
			lv_obj_set_event_cb(cont, btn_handler);
			lv_obj_set_user_data(cont, tv);
		}	
	}
	
	lv_task_create(page_task, 10, LV_TASK_PRIO_LOW, tv);
	lv_tileview_set_tile_act(tv, 0, 2, LV_ANIM_OFF); 
	return tv;
}

运行效果

在这里插入图片描述

<think>嗯,用户想在LVGL框架下实现定时循环播放图片的功能,具体是如何设置定时器来实现自动循环播放呢?首先,我需要回忆一下LVGL的定时器机制。根据引用[2],LVGL的定时器可以通过lv_timer_create创建,然后用lv_timer_set_cb设置回调函数。另外,lv_timer_set_repeat_count可以设置重复次数,如果设为-1的话应该就是无限循环了。不过用户想要的是循环播放图片,可能需要每次定时器触发时切换图片。 接下来,用户需要显示图片,所以得用LVGL的图片控件。可能要用lv_img创建图片对象,然后通过设置不同的src属性来切换图片。记得要初始化图片资源,可能需要把图片文件转换成C数组或者使用文件系统加载。这部分引用里没有详细提到,但根据LVGL的一般用法,应该是这样的步骤。 然后,定时器的回调函数里应该执行切换图片的操作。比如维护一个当前图片索引,每次回调时递增索引,并更新图片对象的src。当索引超过图片数量时,重置为0,实现循环。引用[2]中的例子是设置重复次数为5次,但这里用户需要无限循环,所以可能需要设置repeat_count为-1,或者在回调函数里自己处理循环逻辑。 另外,引用[3]提到了样式的设置,比如背景颜色,虽然这里主要是图片切换,但如果有背景渐变的需求,可能需要结合样式设置。不过用户的问题主要集中在定时器和图片切换,所以这部分可能暂时不需要。 需要注意的问题可能有内存管理,如果图片资源很多,需要确保不会内存泄漏或者频繁加载导致卡顿。还有定时器的间隔时间,比如每1秒切换一次,是否会影响性能。另外,如果使用GUI Guider,根据引用[1],可能需要对应正确版本的LVGL,确保API兼容性。 步骤总结的话,应该是: 1. 初始化图片控件,加载图片资源。 2. 创建定时器,设置回调函数和间隔时间。 3. 在回调函数中切换图片的src属性。 4. 处理循环逻辑,比如索引重置。 可能还需要考虑图片的预加载和释放,特别是在资源有限的嵌入式系统中。另外,是否需要使用动画效果或者过渡效果来平滑切换图片,可以进一步优化用户体验。 最后,确保代码符合LVGL的版本要求,比如使用8.3.1的话,API是否正确。参考引用[1]中的版本对应关系,避免兼容性问题。</think>在 LVGL 中实现图片自动循环播放,需要结合定时器和图片控件操作。以下是具体实现步骤及代码说明: ### 一、基础实现步骤 1. **创建图片控件** ```c lv_obj_t * img = lv_img_create(lv_scr_act()); lv_img_set_src(img, &img1); // 初始图片 ``` 2. **定义定时器回调函数** ```c static uint8_t current_img = 0; extern lv_img_dsc_t img1, img2, img3; // 预加载的图片资源 void timer_cb(lv_timer_t * timer) { lv_obj_t * img = (lv_obj_t *)timer->user_data; current_img = (current_img + 1) % 3; // 循环计数 switch(current_img) { case 0: lv_img_set_src(img, &img1); break; case 1: lv_img_set_src(img, &img2); break; case 2: lv_img_set_src(img, &img3); break; } } ``` 3. **创建并配置定时器** ```c lv_timer_t * timer = lv_timer_create(timer_cb, 1000, img); // 1秒间隔 lv_timer_set_repeat_count(timer, -1); // 无限循环[^2] ``` ### 二、进阶优化方案 1. **资源预加载** ```c // 声明图片资源数组 const lv_img_dsc_t * img_list[] = {&img1, &img2, &img3}; #define IMG_COUNT (sizeof(img_list)/sizeof(img_list[0])) ``` 2. **动态样式设置** ```c lv_style_t style; lv_style_init(&style); lv_style_set_img_recolor_opa(&style, LV_OPA_50); // 添加半透明效果[^3] lv_obj_add_style(img, &style, 0); ``` 3. **带渐变的切换动画** ```c lv_anim_t a; lv_anim_init(&a); lv_anim_set_var(&a, img); lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_style_img_opa); lv_anim_set_values(&a, 0, 255); lv_anim_set_time(&a, 500); lv_anim_set_playback_time(&a, 500); ``` ### 三、注意事项 1. 图片资源需预先转换为 LVGL 支持的 C 数组格式或使用文件系统加载 2. 定时器间隔不宜小于 50ms(参考 LVGL 的默认刷新周期) 3. 使用 GUI Guider 时需注意版本匹配,如 1.8.0 对应 LVGL 8.3.1[^1] 4. 嵌入式系统需确保内存足够存储图片资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风雨依依

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值