5.3. ui
5.3.1. ui 控件介绍
基础控件:LVGL原生基础组件
容器控件:LVGL原生容器组件
菜单控件:杰理开发的专属菜单组件(以库形式提供)
组合控件:由基础控件组合而成的复合组件
自定义控件:杰理开发的专属组件(以库形式提供)
歌词控件:歌词控件demo案例演示
5.3.2. 基础控件
- 页面
页面控件是lvgl中非常重要的一个控件,它可以用来创建多个页面,并且可以切换不同的页面。页面控件有三种类型,分别是
标准页面
、顶层页面
、动态页面
。lv_obj_t * page = lv_page_create(lv_scr_act()); lv_obj_set_size(page, 200, 150); lv_obj_center(page);
使用UI设计工具创建页面:
页面文档
- 按钮
按钮控件,用于触发事件。是LVGL中最基础的控件之一。
lv_obj_t * btn = lv_btn_create(lv_scr_act()); lv_obj_center(btn); lv_obj_add_event_cb(btn, my_event_handler, LV_EVENT_CLICKED, NULL);
使用UI设计工具创建按钮:
按钮文档
- 图片按钮
图片按钮
和按钮
控件类似,但是图片按钮可以设置多个图片,根据不同状态显示不同图片。lv_obj_t * imgbtn = lv_imgbtn_create(lv_scr_act()); lv_imgbtn_set_src(imgbtn, LV_IMGBTN_STATE_RELEASED, NULL, &img_normal, NULL); lv_imgbtn_set_src(imgbtn, LV_IMGBTN_STATE_PRESSED, NULL, &img_pressed, NULL);
使用UI设计工具创建图片按钮:
图片按钮文档
- 标签
标签控件用于显示文本信息。
lv_obj_t * label = lv_label_create(lv_scr_act()); lv_label_set_text(label, "Hello JieLi!"); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
使用UI设计工具创建标签:
标签文档
- 图片
图片控件用于显示图片资源,支持图片遮罩、缩放等功能。
LV_IMG_DECLARE(my_img); lv_obj_t * img = lv_img_create(lv_scr_act()); lv_img_set_src(img, &my_img); lv_obj_center(img);
使用UI设计工具创建图片:
图片文档
- 文本框
文本框控件,用于输入和显示文本。支持虚拟键盘输入、滚动条等功能。
lv_obj_t * ta = lv_textarea_create(lv_scr_act()); lv_textarea_set_placeholder_text(ta, "请输入内容..."); lv_obj_set_size(ta, 200, 80); lv_obj_center(ta);
使用UI设计工具创建文本框:
文本框文档
- 开关
开关控件用于切换两种状态,例如开启和关闭。用户可以通过点击控件来切换其选中状态。
lv_obj_t * sw = lv_switch_create(lv_scr_act()); lv_obj_center(sw); lv_obj_add_event_cb(sw, switch_event_handler, LV_EVENT_VALUE_CHANGED, NULL);
使用UI设计工具创建开关:
开关文档
- 数字微调器
数字微调器控件,用于输入数值。
lv_obj_t * spinbox = lv_spinbox_create(lv_scr_act()); lv_spinbox_set_range(spinbox, 0, 100); lv_spinbox_set_digit_format(spinbox, 3, 0); lv_obj_center(spinbox);
使用UI设计工具创建数字微调器:
数字微调器文档
- 复选框
复选框控件用于在界面上显示一个复选框,用户可以勾选或者取消勾选。
lv_obj_t * cb = lv_checkbox_create(lv_scr_act()); lv_checkbox_set_text(cb, "我同意"); lv_obj_center(cb);
使用UI设计工具创建复选框:
复选框文档
- 下拉框
下拉框控件,用于选择一组选项中的一个。
lv_obj_t * dd = lv_dropdown_create(lv_scr_act()); lv_dropdown_set_options(dd, "选项1\n选项2\n选项3"); lv_obj_center(dd);
使用UI设计工具创建下拉框:
下拉框文档
- 进度条
进度条控件用于显示操作的进度。
lv_obj_t * bar = lv_bar_create(lv_scr_act()); lv_bar_set_range(bar, 0, 100); lv_bar_set_value(bar, 50, LV_ANIM_OFF); lv_obj_center(bar);
使用UI设计工具创建进度条:
进度条文档
- Lottie动画
用于在LVGL中播放Lottie动画的控件。
lv_obj_t * lottie = lv_lottie_create(lv_scr_act()); lv_lottie_set_src(lottie, "S:/anim.json"); lv_obj_center(lottie);
使用UI设计工具创建Lottie动画:
Lottie动画文档
- 帧动画
帧动画是一个通过一系列图片快速切换来模拟动画效果的控件。
lv_obj_t * animimg = lv_animimg_create(lv_scr_act()); lv_animimg_set_src(animimg, frame_imgs, frame_count); lv_animimg_start(animimg);
使用UI设计工具创建帧动画:
帧动画文档
- 图表
图表组件用于在屏幕上显示动态数据,支持多种类型的图表(如折线图、柱状图等),并允许用户自定义轴线和刻度设置。通过配置属性,可以调整网格线的数量、每个序列的数据点数以及更新模式等参数,以适应不同的应用场景。
lv_obj_t * chart = lv_chart_create(lv_scr_act()); lv_obj_set_size(chart, 200, 150); lv_obj_center(chart); lv_chart_series_t * ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y); lv_chart_set_next_value(chart, ser, 10);
使用UI设计工具创建图表:
图表文档
- 滑动条
滑动条控件用于在数值范围内选择一个值。滑动条控件通常用在需要用户输入数值的场景中,例如音量调节、亮度调节等。
lv_obj_t * slider = lv_slider_create(lv_scr_act()); lv_slider_set_range(slider, 0, 100); lv_obj_center(slider);
使用UI设计工具创建滑动条:
滑动条文档
- 弧线
弧线是一个用于显示进度的控件。
lv_obj_t * arc = lv_arc_create(lv_scr_act()); lv_arc_set_range(arc, 0, 100); lv_arc_set_value(arc, 75); lv_obj_center(arc);
使用UI设计工具创建弧线:
弧线文档
- 仪表盘
仪表盘组件用于显示一个数值的范围,通常用来表示速度、温度等。
lv_obj_t * gauge = lv_meter_create(lv_scr_act()); lv_obj_set_size(gauge, 200, 200); lv_obj_center(gauge); lv_meter_indicator_t * indic = lv_meter_add_needle_line(gauge, 4, lv_palette_main(LV_PALETTE_BLUE), -10); lv_meter_set_indicator_value(gauge, indic, 40);
使用UI设计工具创建仪表盘:
仪表盘文档
5.3.3. 菜单控件
- 圆弧菜单
圆弧菜单是一种常见的菜单样式,支持
平铺列表
、左圆弧列表
、右圆弧列表
三种菜单风格。使用UI设计工具创建圆弧菜单:
圆弧菜单文档
- 齿轮菜单
齿轮菜单是一种常见的菜单样式,支持 顺时针、逆时针 两种方向展开菜单项。
使用UI设计工具创建齿轮菜单:
齿轮菜单文档
- 列表菜单
列表菜单是一个用于显示列表的菜单。通过改变不同的
菜单样式
, 可以实现不同风格的列表菜单,也支持用户自定义菜单样式。使用UI设计工具创建列表菜单:
列表菜单文档
- 曲线菜单
曲线菜单控件,用于显示一个圆形菜单,菜单项会以曲线的方式展开。
使用UI设计工具创建曲线菜单:
曲线菜单文档
- 网格菜单
网格菜单是一个用于显示网格布局的菜单。通过改变不同的
菜单样式
, 可以实现不同风格的网格菜单,也支持用户自定义菜单样式。使用UI设计工具创建网格菜单:
网格菜单文档
- 万花筒菜单
万花筒菜单(Spiral Menu)是一种环形菜单,它将多个选项分布在圆形或环形路径上。用户可以通过旋转设备或点击屏幕上的不同位置来选择不同的选项。这种类型的菜单通常用于需要快速访问大量选项的应用程序中,例如游戏、导航应用和工具类应用程序等。
使用UI设计工具创建万花筒菜单:
万花筒菜单文档
5.3.4. 容器控件
- 通用容器
通用容器是一个用来包裹其他控件的容器控件,它可以包含任意数量的子控件,子控件可以是任意类型的控件。
lv_obj_t * cont = lv_obj_create(lv_scr_act()); lv_obj_set_size(cont, 200, 150); lv_obj_center(cont); /* 在容器中添加一个按钮 */ lv_obj_t * btn_in = lv_btn_create(cont); lv_obj_align(btn_in, LV_ALIGN_CENTER, 0, 0); lv_obj_t * label_in = lv_label_create(btn_in); lv_label_set_text(label_in, "按钮"); lv_obj_center(label_in);
使用UI设计工具创建通用容器:
通用容器文档
- Flex布局
Flex布局是一种一维布局,在UI工具上,只能在一个方向上排列元素,可以是水平方向,也可以是垂直方向。
lv_obj_t * flex_cont = lv_obj_create(lv_scr_act()); lv_obj_set_size(flex_cont, 300, 200); lv_obj_center(flex_cont); /* 设置为水平排列 */ lv_obj_set_flex_flow(flex_cont, LV_FLEX_FLOW_ROW); /* 往容器里添加 3 个按钮 */ for(int i = 0; i < 3; i++) { lv_obj_t * btn = lv_btn_create(flex_cont); lv_obj_set_size(btn, 80, 50); lv_obj_t * label = lv_label_create(btn); char buf[16]; lv_snprintf(buf, sizeof(buf), "按钮%d", i+1); lv_label_set_text(label, buf); lv_obj_center(label); }
使用UI设计工具创建Flex布局:
Flex布局文档
5.3.5. 歌词控件
演示案例:
只修改三个文件:lv_example_lyrics_3.c、lvgl_main.c、gui_timeline_timeline.c 。
lv_example_lyrics_3.c:
作用:放了歌词控件的创建、更新、释放函数
/*
* @file lv_example_lyrics_3.c
*
* 演示了如何调用 lv_lyrics 控件和蓝牙播歌实现简单的歌词播放 demo
*/
#include "../../lv_examples.h"
#if 1
#include "os/os_api.h"
#include "lvgl.h"
#define CONFIG_UI_RES_PATH CONFIG_ROOT_PATH // SD 路径
#define CONFIG_FONT_TTF_PATH "storage/sd0/C/xxx.ttf" //字体
#define LYRICS_LETTER_NUM_MAX 256
static char lyrics_example3_text[LYRICS_LETTER_NUM_MAX] = " ";
lv_obj_t *curr_obj_0 = NULL;
lv_obj_t **curr_obj_single = NULL;
int count_of_text = 0;
static char *test_text = "两只老虎跑的快";
//释放歌词
void lyrics_example3_clean(void){
for (int i = 0;i<count_of_text;i++){
lv_anim_del(curr_obj_single[i],NULL);
lv_lyrics_destructor(curr_obj_single[i]);
curr_obj_single[i] = NULL;
}
}
//创建歌词
void lv_example_lyrics_3_letter( lv_obj_t *dest_scr, const char *text, uint16_t font_size, const char *font_file){
lyrics_example3_clean();
size_t text_len = strlen(text);
uint32_t *letter_buf = (uint32_t *)lv_mem_alloc(sizeof(uint32_t) * text_len); // 空间大小最大不会超过 text_len * 4
uint16_t letter_num = 0;
// 解析字符串中的每一个 unicode
int ofs = 0;
while (ofs < text_len) {
uint32_t letter;
uint32_t letter_next;
printf("[chili] %s %d\n", __func__, __LINE__);
_lv_txt_encoded_letter_next_2(text, &letter, &letter_next, &ofs);
printf("ofs = %d; letter = 0x%08x; letter_next = 0x%08x.", ofs, letter, letter_next);
letter_buf[letter_num] = letter;
printf("info.letter_buf[%d] = 0x%08x.", letter_num, letter_buf[letter_num]);
letter_num++;
assert(letter_num < LYRICS_LETTER_NUM_MAX); // 歌词字符数量过大,有需求再修改
}
count_of_text = letter_num;
printf("letter_num = %d.", letter_num);
printf("text_len = %d.",text_len);
curr_obj_single = (lv_obj_t **)malloc(100*sizeof(lv_obj_t *));
for (int i = 0;i<letter_num;i++){
curr_obj_single[i] = lv_lyrics_create(dest_scr, font_file, font_size, letter_buf + i, 1);
//lv_lyrics_set_pos(curr_obj_single[i], 0 + i*70, 0);//正常字间距
lv_lyrics_set_pos(curr_obj_single[i], 0 + i*80, 150);
}
lv_mem_free(letter_buf);
return;
}
//更新歌词
void lv_example_lyrics_3_text_input(void *dest_scr , char *new_text){
size_t text_len = strlen(new_text);
if (text_len > LYRICS_LETTER_NUM_MAX) {
printf("error: new_text is too len. len = %d.", text_len);
return;
}
printf("[%s] new lyrics is [%s]", __func__, new_text);
memcpy(lyrics_example3_text, new_text, text_len);
lyrics_example3_text[text_len] = '\0';
lv_example_lyrics_3_letter(dest_scr,lyrics_example3_text, 64, CONFIG_FONT_TTF_PATH);
}
//调用示例
//在lvgl以外线程使用lvgl_rpc_post_func(),歌词创建在lv_layer_top()页面,test_text为输入歌词
//lvgl_rpc_post_func(lv_example_lyrics_3_text_input, 2, lv_layer_top() , test_text);
#endif
lv_main.c:
作用:在lvgl_v8_main_task中调用demo
变量全局声明和函数定义:
static char *test_text = "测试歌词"; //歌词
lv_obj_t *father_of_curr_obj_0 = NULL; //父控件(可选)
void lyric_test_demo(void){
extern void lv_example_lyrics_3_text_input(void *dest_scr , char *new_text);//外部引用
lv_example_lyrics_3_text_input(father_of_curr_obj_0, test_text); //歌词更新函数
}

lvgl_v8_main_task中的调用:
//jl_gui_init();
while (storage_device_ready() != true) os_time_dly(3);
father_of_curr_obj_0 = lv_obj_create(lv_scr_act());
lyric_test_demo();
gui_timeline_timeline_set_repeat_count(-1); // 无限循环(可选)
gui_timeline_timeline_set_period(500); // 设置一次动画的周期(可选)
gui_timeline_timeline_start(); // ✅ 启动动画

gui_timeline_timeline.c:
作用:实现时间轴动画,完成歌词的平移、旋转、缩放
除了gui_timeline_timeline.c文件以外的文件在其他sdk里应该都是一样的,不一样将其复制过去即可,没有四个文件就自行创建

/*Generate Code, Do NOT Edit!*/
#if LV_USE_GUIBUILDER_SIMULATOR
#include <stdio.h>
#endif
#include <stdlib.h>
#include "lvgl.h"
#include "../gui_guider.h"
#include "./gui_timeline_timeline.h"
extern lv_obj_t *father_of_curr_obj_0;//父控件
extern lv_obj_t **curr_obj_single;//单个字数组
bool first_init = 1; //是否第一次init
extern count_of_text; //text的字数
lv_timeline_timeline_t gui_timeline_timeline;
void set_center(lv_obj_t *obj,int statement){//设置控件obj在父控件中心,statement为1代表是歌词,为0表示普通控件
lv_coord_t width;
lv_coord_t height;
lv_coord_t width_p;
lv_coord_t height_p;
lv_coord_t x;
lv_coord_t y;
if (statement){
lv_lyrics_info *lyrics_info = (lv_lyrics_info *)lv_obj_get_user_data(obj);
width = lyrics_info->curr_fontimg->header.w;
height = lyrics_info->curr_fontimg->header.h;
printf("width = %d , height = %d\n",width,height);
}else{
width = lv_obj_get_width(obj);
height = lv_obj_get_height(obj);
}
lv_obj_t *parent = lv_obj_get_parent(obj);
if (statement){
width_p = 400;
height_p = 400;
}else{
width_p = lv_obj_get_width(parent);
height_p = lv_obj_get_height(parent);
}
x = width_p/2 - width/2;
y = height_p/2 - height/2;
printf("set_center x = %d,y = %d\n",x,y);
if (statement){
lv_lyrics_set_pos(obj, x, y);
}else {
lv_obj_set_x(obj, x);
lv_obj_set_y(obj, y);
}
}
//↓↓下面都是动画回调函数
void gui_timeline_set_lyrics_zoom(void *obj, int32_t v){//缩放动画
lv_lyrics_info *lyrics_info = (lv_lyrics_info *)(((lv_obj_t *)obj)->user_data);
lv_lyrics_set_zoom(obj, v, v);
lv_lyrics_fontimg_redarw(obj);
}
void gui_timeline_set_lyrics_rotation(void *obj, int32_t v){//旋转动画
lv_lyrics_info *lyrics_info = (lv_lyrics_info *)(((lv_obj_t *)obj)->user_data);
lyrics_info->tc_point.x = 0.5f;
lyrics_info->tc_point.y = 0.5f;
lv_lyrics_set_rotation(obj, 0, 0, v);//在动画刷屏时才会绘制
lv_lyrics_fontimg_redarw(obj);
}
void gui_timeline_init(struct _lv_anim_t *a){//开始动画的一些初始化
if (first_init){
lv_obj_set_width(father_of_curr_obj_0, 400);
lv_obj_set_height(father_of_curr_obj_0, 400);
set_center(father_of_curr_obj_0,0);
lv_obj_set_style_bg_opa(father_of_curr_obj_0, LV_OPA_TRANSP, LV_PART_MAIN | LV_STATE_DEFAULT); // 背景透明
lv_obj_set_style_border_width(father_of_curr_obj_0, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // 去边框
lv_obj_set_style_radius(father_of_curr_obj_0, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // 去圆角
lv_obj_set_style_shadow_width(father_of_curr_obj_0, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // 去阴影
first_init = 0;
}
set_center(father_of_curr_obj_0,0);
for (int i = 0;i<count_of_text;i++){
lv_lyrics_set_pos(curr_obj_single[i], 0 + i*80, 150);
}
}
void gui_timeline_set_obj_y(void * var, int32_t v){//平移控件y坐标动画
lv_obj_set_y((lv_obj_t *)var, v);
}
void gui_timeline_set_obj_x(void * var, int32_t v){//平移控件x坐标动画
lv_obj_set_x((lv_obj_t *)var, v);
}
void gui_timeline_set_lyrics_y(void *var,int32_t v){//平移歌词动画
lv_lyrics_set_y((lv_obj_t *)var, v);
}
void gui_timeline_timeline_end_cb(struct _lv_anim_t *a){//结束动画
if(gui_timeline_timeline._repeat_count == -1) {
gui_timeline_timeline_start();
} else if(gui_timeline_timeline._repeat_count > 0) {
gui_timeline_timeline._repeat_count--;
gui_timeline_timeline_start();
}
}
void gui_timeline_set_opa(void *var,int32_t v){//透明度渐变动画
lv_obj_set_style_bg_img_opa((lv_obj_t *)var,v,LV_PART_MAIN);
}
//↑↑上面都是动画回调函数
int32_t gui_timeline_timeline_init(lv_ui *ui){//设置动画持续时间、执行开始时间、给obj绑定动画回调函数初始化
gui_timeline_timeline.timeline = lv_anim_timeline_create();
lv_anim_t home_view_1_1_init;
lv_anim_init(&home_view_1_1_init);
lv_anim_set_var(&home_view_1_1_init, father_of_curr_obj_0);
lv_anim_set_start_cb(&home_view_1_1_init, gui_timeline_init);
lv_anim_set_time(&home_view_1_1_init, 10);
lv_anim_timeline_add(gui_timeline_timeline.timeline, 0, &home_view_1_1_init);
lv_anim_t home_view_1_top_1_0_a;
lv_anim_init(&home_view_1_top_1_0_a);
lv_anim_set_var(&home_view_1_top_1_0_a, father_of_curr_obj_0);
lv_anim_set_early_apply(&home_view_1_top_1_0_a, false);
lv_anim_set_values(&home_view_1_top_1_0_a, 140, -300);
lv_anim_set_exec_cb(&home_view_1_top_1_0_a, gui_timeline_set_obj_y);
lv_anim_set_path_cb(&home_view_1_top_1_0_a, lv_anim_path_linear);
lv_anim_set_time(&home_view_1_top_1_0_a, 2000);
lv_anim_timeline_add(gui_timeline_timeline.timeline, 10, &home_view_1_top_1_0_a);
lv_anim_t home_view_1_left_1_0_a;
lv_anim_init(&home_view_1_left_1_0_a);
lv_anim_set_var(&home_view_1_left_1_0_a, father_of_curr_obj_0);
lv_anim_set_early_apply(&home_view_1_left_1_0_a, false);
lv_anim_set_values(&home_view_1_left_1_0_a, 200, 500);
lv_anim_set_exec_cb(&home_view_1_left_1_0_a, gui_timeline_set_obj_x);
lv_anim_set_path_cb(&home_view_1_left_1_0_a, lv_anim_path_linear);
lv_anim_set_time(&home_view_1_left_1_0_a, 2000);
lv_anim_timeline_add(gui_timeline_timeline.timeline, 10, &home_view_1_left_1_0_a);
for (int i = 0;i<count_of_text;i++){//给每个歌词都绑定下面的动画
lv_anim_t lyrics_example3_play_anim_single;
lv_anim_init(&lyrics_example3_play_anim_single); // 初时化动画变量
lv_anim_set_var(&lyrics_example3_play_anim_single, curr_obj_single[i]); //设置动画关联的对象img
lv_anim_set_early_apply(&lyrics_example3_play_anim_single, false);
lv_anim_set_exec_cb(&lyrics_example3_play_anim_single, gui_timeline_set_lyrics_rotation); //设置动画执行的回调函数set_angle
lv_anim_set_values(&lyrics_example3_play_anim_single, 0, (i%2 == 0)?600:(-600));
lv_anim_set_time(&lyrics_example3_play_anim_single, 1000);
lv_anim_set_path_cb(&lyrics_example3_play_anim_single, lv_anim_path_linear);
lv_anim_set_playback_time(&lyrics_example3_play_anim_single, 1000);
lv_anim_timeline_add(gui_timeline_timeline.timeline, 10, &lyrics_example3_play_anim_single);
lv_anim_t home_view_1_top_1_0_letter;
lv_anim_init(&home_view_1_top_1_0_letter);
lv_anim_set_var(&home_view_1_top_1_0_letter, curr_obj_single[i]);
lv_anim_set_early_apply(&home_view_1_top_1_0_letter, false);
lv_anim_set_values(&home_view_1_top_1_0_letter, 150, (i%2==0)?100:50);
lv_anim_set_exec_cb(&home_view_1_top_1_0_letter, gui_timeline_set_lyrics_y);
lv_anim_set_path_cb(&home_view_1_top_1_0_letter, lv_anim_path_linear);
lv_anim_set_time(&home_view_1_top_1_0_letter, 2000);
lv_anim_timeline_add(gui_timeline_timeline.timeline, 10, &home_view_1_top_1_0_letter);
lv_anim_t home_view_1_top_1_0_letter_opa;
lv_anim_init(&home_view_1_top_1_0_letter_opa);
lv_anim_set_var(&home_view_1_top_1_0_letter_opa, curr_obj_single[i]);
lv_anim_set_early_apply(&home_view_1_top_1_0_letter_opa, false);
lv_anim_set_values(&home_view_1_top_1_0_letter_opa, 255, 0);
lv_anim_set_exec_cb(&home_view_1_top_1_0_letter_opa, gui_timeline_set_opa);
lv_anim_set_path_cb(&home_view_1_top_1_0_letter_opa, lv_anim_path_linear);
lv_anim_set_time(&home_view_1_top_1_0_letter_opa, 1000);
lv_anim_timeline_add(gui_timeline_timeline.timeline, 10, &home_view_1_top_1_0_letter_opa);
}
lv_anim_t timeline_end_a;
lv_anim_init(&timeline_end_a);
lv_anim_set_time(&timeline_end_a, gui_timeline_timeline._period);
lv_anim_set_deleted_cb(&timeline_end_a, gui_timeline_timeline_end_cb);
lv_anim_timeline_add(gui_timeline_timeline.timeline, 1100, &timeline_end_a);
return 0;
}
//↓↓下面都是默认存在的函数(无需修改)
void gui_timeline_timeline_start(){
if (gui_timeline_timeline.timeline) {
int32_t temp_repeat_count = gui_timeline_timeline._repeat_count;
gui_timeline_timeline._repeat_count = 0;
lv_anim_timeline_del(gui_timeline_timeline.timeline);
gui_timeline_timeline._repeat_count = temp_repeat_count;
}
int32_t res = gui_timeline_timeline_init(&guider_ui);
if(res != -1) {
lv_anim_timeline_start(gui_timeline_timeline.timeline);
}
}
void gui_timeline_timeline_stop(){
gui_timeline_timeline._repeat_count = 0;
if(gui_timeline_timeline.timeline) {
lv_anim_timeline_stop(gui_timeline_timeline.timeline);
}
}
void gui_timeline_timeline_delete(){
gui_timeline_timeline._repeat_count = 0;
gui_timeline_timeline._period = 0;
if(gui_timeline_timeline.timeline) {
lv_anim_timeline_del(gui_timeline_timeline.timeline);
gui_timeline_timeline.timeline = NULL;
}
}
void gui_timeline_timeline_set_period(uint32_t period){
gui_timeline_timeline._period = period;
}
void gui_timeline_timeline_set_repeat_count(int32_t count){
gui_timeline_timeline._repeat_count = count;
}
demo中的所有歌词一起平移是用了一个父控件实现的father_of_curr_obj_0
其他动画的回调函数逻辑都比较易懂,看代码即可,下面举个例子 :

最终效果:

下一页详细查看杰理UI工具的用法