RYMCU

LVGL双向链表实现页面切换

Hugh 6 月前
# LVGL # 链表 # STM32移植

1.概述

通过 LVGL 双向链表实现页面切换功能,使用星允派 Nebula pi STM32F103 开发板平台,板子 2.8TFT 液晶触摸显示器。实现功能:创建四个颜色不同的页面,通过手势上/下/左/右滑动依次切换界面。

2.主函数

依次创建 4 个页面,初始化链表,并显示页面 1

void lv_example_anim_1(void)
{
	create_page1();
	create_page2();
	create_page3();
	create_page4();	
	
	ry_list_init();//初始化链表
	
	lv_scr_load(one);//显示page1
	
	LV_LOG_USER("begin");
}

3.链表初始化

初始化链表,并添加 4 个页面。

static lv_obj_t *one_btn,*two_btn,*three_btn,*four_btn;
static lv_obj_t *label,*label2,*label3,*label4;

static lv_obj_t *one,*two,*three,*four;

typedef struct my_page
{
	uint32_t obj_addr;
} my_page_t; //结构体存储页面地址

lv_ll_t ll_test;

my_page_t *page_temp;
/*----------------------------------------------------------------------------------------------
*初始化链表,将页面依次添加到链表,并指向头节点
*
-------------------------------------------------------------------------------------------------*/
void ry_list_init(void)
{	
	_lv_ll_init(&ll_test, sizeof(my_page_t));

	page_temp = _lv_ll_ins_head(&ll_test);
	page_temp->obj_addr = (uint32_t)four;
	page_temp = _lv_ll_ins_head(&ll_test);
	page_temp->obj_addr = (uint32_t)three;
	page_temp = _lv_ll_ins_head(&ll_test);
	page_temp->obj_addr = (uint32_t)two;
	page_temp = _lv_ll_ins_head(&ll_test);
	page_temp->obj_addr = (uint32_t)one;
	
	page_temp = _lv_ll_get_head(&ll_test);
}

4.创建页面并关联手势事件

/*--------------------------------------------------------------------------------------------------
*创建4个不同颜色页面,并关联手势事件
*
---------------------------------------------------------------------------------------------------*/
void create_page1(void)
{
	one = lv_obj_create(NULL); //在默认屏上创建obj对象
	lv_obj_set_style_bg_color(one,lv_color_hex(0xeeffcc), LV_STATE_DEFAULT); // obj背景色设成黄色
	lv_obj_set_size(one, LV_HOR_RES, LV_VER_RES); // 设置到屏幕大小
	
	one_btn = lv_btn_create(one);
	lv_obj_align(one_btn, LV_ALIGN_TOP_MID, 0, 20);

	label = lv_label_create(one_btn);             // 创建label
	lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);         // label居屏幕中心对齐
	lv_label_set_text(label, "ONE");                    // label显示ONE
	lv_obj_add_event_cb(one,ry_gesture_event,LV_EVENT_GESTURE,NULL);
}
void create_page2(void)
{
	two = lv_obj_create(NULL); // 创建新屏幕但未加载到显示
	lv_obj_set_style_bg_color(two,lv_color_hex(0x00d8db), LV_STATE_DEFAULT); // 背影色设成蓝色
	lv_obj_set_size(two, LV_HOR_RES, LV_VER_RES); //设置到屏幕大小

	two_btn = lv_btn_create(two);
	lv_obj_align(two_btn, LV_ALIGN_TOP_MID, 0, 20);

	label2 = lv_label_create(two_btn);                       // 创建label
	lv_obj_align(label2, LV_ALIGN_CENTER, 0, 0);         // 居中对齐
	lv_label_set_text(label2, "TWO");                    // label上显示TWO
	lv_obj_add_event_cb(two,ry_gesture_event,LV_EVENT_GESTURE,NULL);
}
void create_page3(void)
{
	three = lv_obj_create(NULL); // 创建新屏幕但未加载到显示
	lv_obj_set_style_bg_color(three,lv_color_hex(0x00FF00), LV_STATE_DEFAULT); // 背影色设成蓝色
	lv_obj_set_size(three, LV_HOR_RES, LV_VER_RES); //设置到屏幕大小

	three_btn = lv_btn_create(three);
	lv_obj_align(three_btn, LV_ALIGN_TOP_MID, 0, 20);

	label3 = lv_label_create(three_btn);                       // 创建label
	lv_obj_align(label3, LV_ALIGN_CENTER, 0, 0);         // 居中对齐
	lv_label_set_text(label3, "THREE");                    // label上显示THREE

	lv_obj_add_event_cb(three,ry_gesture_event,LV_EVENT_GESTURE,NULL);
}
void create_page4(void)
{
	four = lv_obj_create(NULL); // 创建新屏幕但未加载到显示
	lv_obj_set_style_bg_color(four,lv_color_hex(0x0000FF), LV_STATE_DEFAULT); // 背影色设成蓝色
	lv_obj_set_size(four, LV_HOR_RES, LV_VER_RES); //设置到屏幕大小

	four_btn = lv_btn_create(four);
	lv_obj_align(four_btn, LV_ALIGN_TOP_MID, 0, 20);

	label4 = lv_label_create(four_btn);                       // 创建label
	lv_obj_align(label4, LV_ALIGN_CENTER, 0, 0);         // 居中对齐
	lv_label_set_text(label4, "FOUR");                    // label上显示FOUR

	lv_obj_add_event_cb(four,ry_gesture_event,LV_EVENT_GESTURE,NULL);
}

5.手势事件函数中处理页面切换

核心内容为:根据手势前后移动节点实现页面切换显示。

/*--------------------------------------------------------------------------------------------------
*获取节点
*
-------------------------------------------------------------------------------------------------*/
void ry_get_prev(void)
{
	page_temp = _lv_ll_get_prev(&ll_test,page_temp);
	if(page_temp == NULL)
	{
		page_temp = _lv_ll_get_head(&ll_test);
		LV_LOG_USER("the begin page,no more!");
	}
}
void ry_get_next(void)
{
	page_temp = _lv_ll_get_next(&ll_test,page_temp);
	if(page_temp == NULL)
	{
		page_temp = _lv_ll_get_tail(&ll_test);
		LV_LOG_USER("the end page,no more!");
	}
}
/*------------------------------------------------------------------------------------------------
*手势事件函数
*
-------------------------------------------------------------------------------------------------*/
void ry_gesture_event(lv_event_t *e)
{
	lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());//获取手势方向
	lv_obj_t *target_obj = lv_event_get_target_obj(e);

	switch(dir)
	{
		case LV_DIR_TOP://从上往下
		{
			ry_get_prev();
			lv_scr_load_anim((lv_obj_t *)(page_temp->obj_addr), LV_SCR_LOAD_ANIM_OUT_TOP, 1000, 0, false);
			break;
		}
		case LV_DIR_BOTTOM://从下往上
		{
			ry_get_next();
			lv_scr_load_anim((lv_obj_t *)(page_temp->obj_addr), LV_SCR_LOAD_ANIM_OUT_BOTTOM, 1000, 0, false);
			break;
		}
		case LV_DIR_LEFT://从左往右
		{
			ry_get_next();
			lv_scr_load_anim((lv_obj_t *)(page_temp->obj_addr), LV_SCR_LOAD_ANIM_OUT_LEFT, 1000, 0, false);
			break;
		}
		case LV_DIR_RIGHT://从右往左
		{
			ry_get_prev();	
			lv_scr_load_anim((lv_obj_t *)(page_temp->obj_addr), LV_SCR_LOAD_ANIM_OUT_RIGHT, 1000, 0, false);
			break;
		}
		default:
			break;
	}

}
后发布评论