当前位置: 首页 > news >正文

[LVGL] 从0开始,学LVGL:基础构建篇 - 掌握UI的核心构建块

第2部分:基础构建篇 - 掌握UI的核心构建块

文章目录

  • **第2部分:基础构建篇 - 掌握UI的核心构建块**
    • **第3章:LVGL的对象模型与核心概念**
      • **3.1 万物皆对象:理解LVGL的面向对象设计**
      • **3.2 对象树:理解父子关系**
      • **3.3 屏幕:对象的根容器**
      • **3.4 实战:创建你的第一个对象树**
    • **第4章:让界面"活"起来 - 样式系统入门**
      • **4.1 为什么需要样式系统?**
      • **4.2 样式的数学模型**
      • **4.3 理解样式状态**
      • **4.4 创建和应用样式**
      • **4.5 常用样式属性详解**
    • **第5章:基础控件(一)- 标签、按钮与基础容器**
      • **5.1 标签:文字的载体**
      • **5.2 按钮:交互的基础**
      • **5.3 基础容器:布局的基石**
    • **第6章:基础控件(二)- 滑块、开关、进度条**
      • **6.1 滑块:精确的数值输入**
      • **6.2 开关:二进制状态选择**
      • **6.3 进度条:操作反馈与状态显示**
      • **6.4 综合实战:创建简易调光器界面**
      • **本章总结与挑战**

第3章:LVGL的对象模型与核心概念

3.1 万物皆对象:理解LVGL的面向对象设计

在LVGL中,一切可视元素都是对象。按钮是对象,标签是对象,屏幕本身也是一个对象。这种统一的对象模型带来了极大的灵活性和一致性。

从面向对象的角度看,LVGL实现了一个继承体系

«核心对象»
lv_obj_t
-type
-parent
-children
-style_list
-event_cb
+coords
+...
lv_label
-text
+set_text()
+get_text()
lv_button
+...
lv_slider
-value
+set_value()
+get_value()

所有控件都继承自基础对象 lv_obj_t,这意味着:

  • 所有对象都有共同的基本属性(位置、大小、父对象等)
  • 所有对象都支持共同的操作(创建、删除、移动、设置样式等)
  • 每个派生对象添加自己特有的功能(如标签的文本、滑块的数值)

3.2 对象树:理解父子关系

LVGL通过父子关系构建了一个对象树结构,这决定了:

  1. 渲染顺序:父对象先渲染,子对象后渲染
  2. 坐标系统:子对象的坐标相对于父对象
  3. 可见性:如果父对象不可见,所有子对象都不可见
  4. 生命周期:删除父对象会自动删除所有子对象

对象树示例:

屏幕 lv_scr_act
容器 Container
按钮 Button
标签 Label 1
标签 Label 2
按钮内标签

3.3 屏幕:对象的根容器

屏幕是对象树的根节点。每个LVGL应用至少有一个屏幕:

/* 获取当前活动屏幕 */
lv_obj_t * screen = lv_scr_act();/* 创建新的屏幕 */
lv_obj_t * new_screen = lv_obj_create(NULL);/* 切换到新屏幕 */
lv_scr_load(new_screen);

3.4 实战:创建你的第一个对象树

让我们通过代码来理解这些概念:

#include <lvgl.h>
#include <lv_drivers/display/monitor.h>
#include <lv_drivers/indev/mouse.h>
#include <stdlib.h>// ... 省略初始化代码(与第一部分相同)int main(void) {// LVGL初始化(省略,参考第一部分)/********************* 创建对象树********************/// 获取当前活动屏幕lv_obj_t * screen = lv_scr_act();// 1. 创建一个容器作为父对象lv_obj_t * container = lv_obj_create(screen);lv_obj_set_size(container, 200, 150);      // 设置大小lv_obj_set_pos(container, 50, 50);         // 设置位置lv_obj_set_style_bg_color(container, lv_color_hex(0xE0E0E0), 0); // 浅灰色背景// 2. 在容器内创建标签(子对象)lv_obj_t * label1 = lv_label_create(container);lv_label_set_text(label1, "子标签 1");lv_obj_set_pos(label1, 10, 10);            // 相对于容器的位置// 3. 在容器内创建另一个标签lv_obj_t * label2 = lv_label_create(container);lv_label_set_text(label2, "子标签 2");lv_obj_set_pos(label2, 10, 40);// 4. 直接在屏幕上创建按钮(屏幕的子对象)lv_obj_t * button = lv_btn_create(screen);lv_obj_set_size(button, 120, 50);lv_obj_set_pos(button, 300, 50);// 5. 在按钮内创建标签(按钮的子对象)lv_obj_t * btn_label = lv_label_create(button);lv_label_set_text(btn_label, "按钮");lv_obj_center(btn_label);// 主循环(省略)while(1) {lv_timer_handler();SDL_Delay(5);}return 0;
}

关键API解析:

  • lv_xxx_create(parent) - 创建对象,指定父对象
  • lv_obj_set_size(obj, width, height) - 设置对象大小
  • lv_obj_set_pos(obj, x, y) - 设置对象位置
  • lv_obj_center(obj) - 让对象在父对象中居中

第4章:让界面"活"起来 - 样式系统入门

4.1 为什么需要样式系统?

样式系统让UI设计实现了内容与表现的分离。想象一下,如果没有样式系统,你要修改应用中所有按钮的颜色,就需要遍历每个按钮逐一设置。有了样式系统,你只需要修改样式定义,所有使用该样式的按钮都会自动更新。

4.2 样式的数学模型

在LVGL中,样式可以被看作一个从状态空间视觉属性的映射函数:

设:

  • S = { s 1 , s 2 , . . . , s n } S = \{s_1, s_2, ..., s_n\} S={s1,s2,...,sn} 是对象的所有可能状态集合
  • A = { a 1 , a 2 , . . . , a m } A = \{a_1, a_2, ..., a_m\} A={a1,a2,...,am} 是所有可设置的视觉属性集合

那么样式函数 f f f 定义为:
f : S → A f: S \rightarrow A f:SA

对于每个状态 s i s_i si,样式系统返回对应的属性集合 A i A_i Ai

4.3 理解样式状态

LVGL对象可以同时处于多个状态,常见状态包括:

状态描述触发条件
LV_STATE_DEFAULT默认状态对象创建时的初始状态
LV_STATE_PRESSED按下状态对象被点击或触摸时
LV_STATE_FOCUSED获得焦点通过键盘或编码器导航时
LV_STATE_DISABLED禁用状态对象被禁用时
LV_STATE_CHECKED选中状态开关、复选框等被选中时

状态可以组合使用:

// 组合状态:默认 + 按下
lv_state_t state = LV_STATE_DEFAULT | LV_STATE_PRESSED;

4.4 创建和应用样式

样式创建流程:

创建样式对象
设置默认状态属性
设置其他状态属性
应用到目标对象

代码示例:创建精美的按钮样式

#include <lvgl.h>// ... 省略初始化代码int main(void) {// LVGL初始化(省略)/********************* 1. 创建样式对象********************/static lv_style_t style_btn_default;    // 默认状态样式static lv_style_t style_btn_pressed;    // 按下状态样式static lv_style_t style_btn_disabled;   // 禁用状态样式// 初始化样式对象lv_style_init(&style_btn_default);lv_style_init(&style_btn_pressed);lv_style_init(&style_btn_disabled);/********************* 2. 配置默认状态样式(蓝色渐变按钮)********************/lv_style_set_bg_color(&style_btn_default, lv_color_hex(0x2196F3));      // 主蓝色lv_style_set_bg_grad_color(&style_btn_default, lv_color_hex(0x1976D2)); // 渐变深蓝色lv_style_set_bg_grad_dir(&style_btn_default, LV_GRAD_DIR_VER);          // 垂直渐变lv_style_set_radius(&style_btn_default, 12);                            // 圆角半径lv_style_set_border_width(&style_btn_default, 0);                       // 无边框lv_style_set_shadow_width(&style_btn_default, 8);                       // 阴影大小lv_style_set_shadow_color(&style_btn_default, lv_color_hex(0x1A237E));  // 阴影颜色lv_style_set_shadow_ofs_y(&style_btn_default, 4);                       // 阴影Y偏移// 文字样式lv_style_set_text_color(&style_btn_default, lv_color_white());          // 白色文字/********************* 3. 配置按下状态样式(深蓝色)********************/lv_style_set_bg_color(&style_btn_pressed, lv_color_hex(0x1976D2));      // 深蓝色lv_style_set_bg_grad_color(&style_btn_pressed, lv_color_hex(0x0D47A1)); // 更深的蓝色lv_style_set_shadow_ofs_y(&style_btn_pressed, 2);                       // 按下时阴影变小lv_style_set_translate_y(&style_btn_pressed, 2);                        // 按下时下沉效果/********************* 4. 配置禁用状态样式(灰色)********************/lv_style_set_bg_color(&style_btn_disabled, lv_color_hex(0x9E9E9E));     // 灰色lv_style_set_bg_grad_color(&style_btn_disabled, lv_color_hex(0x757575)); // 深灰色lv_style_set_text_color(&style_btn_disabled, lv_color_hex(0xE0E0E0));   // 浅灰色文字/********************* 5. 创建按钮并应用样式********************/lv_obj_t * btn1 = lv_btn_create(lv_scr_act());lv_obj_set_size(btn1, 120, 50);lv_obj_set_pos(btn1, 50, 50);// 应用样式到不同状态lv_obj_add_style(btn1, &style_btn_default, LV_STATE_DEFAULT);lv_obj_add_style(btn1, &style_btn_pressed, LV_STATE_PRESSED);lv_obj_add_style(btn1, &style_btn_disabled, LV_STATE_DISABLED);// 添加按钮文字lv_obj_t * label1 = lv_label_create(btn1);lv_label_set_text(label1, "启用状态");lv_obj_center(label1);/********************* 6. 创建禁用状态的按钮用于对比********************/lv_obj_t * btn2 = lv_btn_create(lv_scr_act());lv_obj_set_size(btn2, 120, 50);lv_obj_set_pos(btn2, 200, 50);// 应用相同的样式lv_obj_add_style(btn2, &style_btn_default, LV_STATE_DEFAULT);lv_obj_add_style(btn2, &style_btn_pressed, LV_STATE_PRESSED);lv_obj_add_style(btn2, &style_btn_disabled, LV_STATE_DISABLED);// 设置按钮为禁用状态lv_obj_add_state(btn2, LV_STATE_DISABLED);// 添加按钮文字lv_obj_t * label2 = lv_label_create(btn2);lv_label_set_text(label2, "禁用状态");lv_obj_center(label2);// 主循环(省略)while(1) {lv_timer_handler();SDL_Delay(5);}return 0;
}

4.5 常用样式属性详解

LVGL提供了丰富的样式属性,主要分为以下几类:

背景属性

lv_style_set_bg_color(style, color);          // 背景颜色
lv_style_set_bg_grad_color(style, color);     // 渐变颜色
lv_style_set_bg_grad_dir(style, dir);         // 渐变方向
lv_style_set_bg_main_stop(style, value);      // 主颜色停止点
lv_style_set_bg_grad_stop(style, value);      // 渐变颜色停止点
lv_style_set_bg_opa(style, opa);              // 背景透明度 (0-255)

边框属性

lv_style_set_border_color(style, color);      // 边框颜色
lv_style_set_border_width(style, width);      // 边框宽度
lv_style_set_border_opa(style, opa);          // 边框透明度
lv_style_set_border_side(style, side);        // 边框边 (LEFT/RIGHT/TOP/BOTTOM/ALL)

轮廓属性

lv_style_set_outline_color(style, color);     // 轮廓颜色
lv_style_set_outline_width(style, width);     // 轮廓宽度
lv_style_set_outline_pad(style, value);       // 轮廓填充

阴影属性

lv_style_set_shadow_color(style, color);      // 阴影颜色
lv_style_set_shadow_width(style, width);      // 阴影大小
lv_style_set_shadow_ofs_x(style, value);      // 阴影X偏移
lv_style_set_shadow_ofs_y(style, value);      // 阴影Y偏移

几何属性

lv_style_set_width(style, value);             // 宽度
lv_style_set_height(style, value);            // 高度
lv_style_set_x(style, value);                 // X坐标
lv_style_set_y(style, value);                 // Y坐标
lv_style_set_align(style, align);             // 对齐方式
lv_style_set_transform_width(style, value);   // 变换宽度
lv_style_set_transform_height(style, value);  // 变换高度

文字属性

lv_style_set_text_color(style, color);        // 文字颜色
lv_style_set_text_font(style, font);          // 字体
lv_style_set_text_opa(style, opa);            // 文字透明度
lv_style_set_text_letter_space(style, value); // 字母间距
lv_style_set_text_line_space(style, value);   // 行间距

第5章:基础控件(一)- 标签、按钮与基础容器

5.1 标签:文字的载体

标签是LVGL中最基本的文本显示控件。

核心功能:

  • 显示静态或动态文本
  • 支持文本换行和滚动
  • 支持文本对齐方式
  • 支持长文本模式

数学表达:
标签的渲染可以看作一个文本布局函数:
R = L ( T , F , A , M ) R = L(T, F, A, M) R=L(T,F,A,M)

其中:

  • R R R = 渲染结果
  • T T T = 文本内容
  • F F F = 字体属性
  • A A A = 对齐方式
  • M M M = 长文本模式

代码示例:标签的各种用法

// 创建基础标签
lv_obj_t * label1 = lv_label_create(lv_scr_act());
lv_label_set_text(label1, "这是基础标签");
lv_obj_set_pos(label1, 10, 10);// 创建长文本标签(自动换行)
lv_obj_t * label2 = lv_label_create(lv_scr_act());
lv_obj_set_size(label2, 200, 100);  // 必须设置大小才能换行
lv_obj_set_pos(label2, 10, 40);
lv_label_set_text(label2, "这是一个很长的文本,它会在标签边界处自动换行,确保所有内容都能正确显示。");
lv_label_set_long_mode(label2, LV_LABEL_LONG_WRAP);  // 换行模式// 创建滚动文本标签
lv_obj_t * label3 = lv_label_create(lv_scr_act());
lv_obj_set_size(label3, 150, 25);
lv_obj_set_pos(label3, 10, 150);
lv_label_set_text(label3, "这是一个会水平滚动的文本,当文本过长时...");
lv_label_set_long_mode(label3, LV_LABEL_LONG_SCROLL);  // 滚动模式// 创建居中对齐标签
lv_obj_t * label4 = lv_label_create(lv_scr_act());
lv_obj_set_size(label4, 200, 30);
lv_obj_set_pos(label4, 10, 190);
lv_label_set_text(label4, "居中对齐的文本");
lv_obj_set_style_text_align(label4, LV_TEXT_ALIGN_CENTER, 0);// 动态更新文本
static int counter = 0;
lv_obj_t * dynamic_label = lv_label_create(lv_scr_act());
lv_obj_set_pos(dynamic_label, 10, 230);// 在定时器中更新文本
lv_timer_t * timer = lv_timer_create([](lv_timer_t * timer) {static int count = 0;lv_label_set_text_fmt((lv_obj_t *)timer->user_data, "计数器: %d", count++);
}, 1000, dynamic_label);

5.2 按钮:交互的基础

按钮是最常用的交互控件,它本身是一个容器,通常内部包含标签。

按钮状态机:

按下
释放
禁用
启用
切换(如开关)
取消切换
DEFAULT
PRESSED
DISABLED
CHECKED

代码示例:创建功能性按钮

// 创建普通按钮
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 100, 40);
lv_obj_set_pos(btn, 250, 50);// 添加按钮文字
lv_obj_t * btn_label = lv_label_create(btn);
lv_label_set_text(btn_label, "点击我");
lv_obj_center(btn_label);// 创建开关式按钮
lv_obj_t * toggle_btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(toggle_btn, 100, 40);
lv_obj_set_pos(toggle_btn, 250, 100);
lv_obj_add_flag(toggle_btn, LV_OBJ_FLAG_CHECKABLE);  // 使按钮可切换lv_obj_t * toggle_label = lv_label_create(toggle_btn);
lv_label_set_text(toggle_label, "开关");
lv_obj_center(toggle_label);

5.3 基础容器:布局的基石

容器本身没有特定的外观,主要用于组织和布局子对象。

容器的核心作用:

  • 分组相关控件
  • 简化布局管理
  • 控制子对象的可见性和位置

代码示例:使用容器组织界面

// 创建主容器
lv_obj_t * container = lv_obj_create(lv_scr_act());
lv_obj_set_size(container, 280, 180);
lv_obj_set_pos(container, 10, 270);
lv_obj_set_flex_flow(container, LV_FLEX_FLOW_COLUMN);  // 垂直排列
lv_obj_set_style_pad_all(container, 10, 0);            // 内边距// 在容器内创建标题标签
lv_obj_t * title = lv_label_create(container);
lv_label_set_text(title, "设置面板");
lv_obj_set_style_text_font(title, &lv_font_montserrat_16, 0);// 创建水平排列的按钮组
lv_obj_t * btn_container = lv_obj_create(container);
lv_obj_set_size(btn_container, lv_pct(100), 50);
lv_obj_set_flex_flow(btn_container, LV_FLEX_FLOW_ROW); // 水平排列
lv_obj_set_style_bg_opa(btn_container, LV_OPA_0, 0);   // 透明背景
lv_obj_set_style_border_width(btn_container, 0, 0);    // 无边框// 在按钮容器中添加多个按钮
for(int i = 0; i < 3; i++) {lv_obj_t * btn = lv_btn_create(btn_container);lv_obj_set_flex_grow(btn, 1);  // 等分宽度lv_obj_t * label = lv_label_create(btn);lv_label_set_text_fmt(label, "选项 %d", i + 1);lv_obj_center(label);
}

第6章:基础控件(二)- 滑块、开关、进度条

6.1 滑块:精确的数值输入

滑块允许用户通过拖动来选择特定范围内的数值。

滑块的值映射:
滑块将一个物理位置映射到一个数值范围内:

v a l u e = m i n + p o s i t i o n m a x _ p o s i t i o n × ( m a x − m i n ) value = min + \frac{position}{max\_position} \times (max - min) value=min+max_positionposition×(maxmin)

其中:

  • v a l u e value value = 当前值
  • m i n min min, m a x max max = 值范围
  • p o s i t i o n position position = 滑块当前位置
  • m a x _ p o s i t i o n max\_position max_position = 滑块最大可移动范围

代码示例:创建多功能滑块

// 创建水平滑块
lv_obj_t * slider1 = lv_slider_create(lv_scr_act());
lv_obj_set_size(slider1, 200, 20);
lv_obj_set_pos(slider1, 400, 50);
lv_slider_set_range(slider1, 0, 100);        // 设置范围 0-100
lv_slider_set_value(slider1, 30, LV_ANIM_OFF); // 设置初始值// 创建垂直滑块
lv_obj_t * slider2 = lv_slider_create(lv_scr_act());
lv_obj_set_size(slider2, 20, 150);
lv_obj_set_pos(slider2, 450, 80);
lv_slider_set_range(slider2, 0, 100);
lv_slider_set_value(slider2, 70, LV_ANIM_OFF);// 显示滑块值的标签
lv_obj_t * slider_label = lv_label_create(lv_scr_act());
lv_obj_set_pos(slider_label, 400, 80);// 滑块事件处理
lv_obj_add_event_cb(slider1, [](lv_event_t * e) {lv_obj_t * slider = lv_event_get_target(e);int32_t value = lv_slider_get_value(slider);// 更新标签显示lv_label_set_text_fmt((lv_obj_t *)lv_event_get_user_data(e), "值: %d%%", value);
}, LV_EVENT_VALUE_CHANGED, slider_label);

6.2 开关:二进制状态选择

开关用于表示开/关、是/否等二进制状态。

开关的布尔逻辑:
s t a t e = { true if checked false if unchecked state = \begin{cases} \text{true} & \text{if checked} \\ \text{false} & \text{if unchecked} \end{cases} state={truefalseif checkedif unchecked

代码示例:创建状态开关

// 创建开关
lv_obj_t * sw = lv_switch_create(lv_scr_act());
lv_obj_set_pos(sw, 400, 150);// 创建开关状态标签
lv_obj_t * sw_label = lv_label_create(lv_scr_act());
lv_obj_set_pos(sw_label, 480, 150);
lv_label_set_text(sw_label, "关");// 开关事件处理
lv_obj_add_event_cb(sw, [](lv_event_t * e) {lv_obj_t * sw = lv_event_get_target(e);bool state = lv_obj_has_state(sw, LV_STATE_CHECKED);lv_label_set_text((lv_obj_t *)lv_event_get_user_data(e), state ? "开" : "关");
}, LV_EVENT_VALUE_CHANGED, sw_label);

6.3 进度条:操作反馈与状态显示

进度条用于显示操作的进度或系统的状态。

进度计算:
p r o g r e s s = c u r r e n t − m i n m a x − m i n × 100 % progress = \frac{current - min}{max - min} \times 100\% progress=maxmincurrentmin×100%

代码示例:创建动态进度条

// 创建进度条
lv_obj_t * progress_bar = lv_bar_create(lv_scr_act());
lv_obj_set_size(progress_bar, 200, 20);
lv_obj_set_pos(progress_bar, 400, 200);
lv_bar_set_range(progress_bar, 0, 100);      // 设置范围
lv_bar_set_value(progress_bar, 0, LV_ANIM_OFF);// 进度标签
lv_obj_t * progress_label = lv_label_create(lv_scr_act());
lv_obj_set_pos(progress_label, 400, 230);
lv_label_set_text(progress_label, "0%");// 模拟进度更新
static int progress = 0;
lv_timer_t * progress_timer = lv_timer_create([](lv_timer_t * timer) {if(progress >= 100) {lv_timer_del(timer);return;}progress += 2;lv_bar_set_value((lv_obj_t *)timer->user_data, progress, LV_ANIM_ON);// 更新标签lv_label_set_text_fmt(progress_label, "%d%%", progress);
}, 100, progress_bar);

6.4 综合实战:创建简易调光器界面

现在让我们综合运用所学知识,创建一个完整的调光器控制面板:

void create_dimmer_interface() {// 创建主容器lv_obj_t * container = lv_obj_create(lv_scr_act());lv_obj_set_size(container, 300, 200);lv_obj_align(container, LV_ALIGN_TOP_RIGHT, -20, 20);lv_obj_set_style_bg_color(container, lv_color_hex(0x2C3E50), 0);lv_obj_set_style_radius(container, 15, 0);// 标题lv_obj_t * title = lv_label_create(container);lv_label_set_text(title, "LED调光器");lv_obj_set_style_text_color(title, lv_color_white(), 0);lv_obj_set_style_text_font(title, &lv_font_montserrat_18, 0);lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 15);// 亮度滑块lv_obj_t * brightness_slider = lv_slider_create(container);lv_obj_set_size(brightness_slider, 200, 20);lv_obj_align(brightness_slider, LV_ALIGN_TOP_MID, 0, 60);lv_slider_set_range(brightness_slider, 0, 100);lv_slider_set_value(brightness_slider, 75, LV_ANIM_OFF);// 亮度标签lv_obj_t * brightness_label = lv_label_create(container);lv_obj_set_style_text_color(brightness_label, lv_color_white(), 0);lv_obj_align_to(brightness_label, brightness_slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);// 开关控制lv_obj_t * power_switch = lv_switch_create(container);lv_obj_align(power_switch, LV_ALIGN_TOP_MID, 0, 120);lv_obj_t * power_label = lv_label_create(container);lv_label_set_text(power_label, "电源");lv_obj_set_style_text_color(power_label, lv_color_white(), 0);lv_obj_align_to(power_label, power_switch, LV_ALIGN_OUT_LEFT_MID, -10, 0);// 事件处理:更新亮度显示lv_obj_add_event_cb(brightness_slider, [](lv_event_t * e) {lv_obj_t * slider = lv_event_get_target(e);int32_t value = lv_slider_get_value(slider);lv_label_set_text_fmt((lv_obj_t *)lv_event_get_user_data(e), "亮度: %d%%", value);}, LV_EVENT_VALUE_CHANGED, brightness_label);// 初始化亮度显示lv_event_send(brightness_slider, LV_EVENT_VALUE_CHANGED, NULL);// 事件处理:开关状态lv_obj_add_event_cb(power_switch, [](lv_event_t * e) {lv_obj_t * sw = lv_event_get_target(e);bool enabled = lv_obj_has_state(sw, LV_STATE_CHECKED);// 这里可以添加实际的LED控制逻辑printf("LED %s\n", enabled ? "开启" : "关闭");}, LV_EVENT_VALUE_CHANGED, NULL);
}

在main函数中调用:

int main(void) {// ... 初始化代码create_dimmer_interface();// ... 主循环
}

本章总结与挑战

恭喜!你已经掌握了LVGL的核心构建块。你现在能够:

  1. 理解LVGL的面向对象模型和对象树概念
  2. 创建和配置丰富的样式系统,实现精美的UI效果
  3. 熟练使用基础控件:标签、按钮、容器、滑块、开关、进度条
  4. 组合多个控件创建功能完整的用户界面

小挑战(巩固练习):

  1. 样式进阶:为调光器界面添加按下状态的样式效果,让按钮和滑块在交互时有视觉反馈。
  2. 布局优化:使用容器和Flex布局重新组织调光器界面,使其在不同屏幕尺寸下都能良好显示。
  3. 功能扩展:在调光器界面中添加颜色选择功能,使用多个滑块分别控制RGB值。
  4. 状态联动:实现当电源开关关闭时,自动禁用亮度滑块并将其值设置为0。

在下一篇文章中,我们将深入探讨事件系统高级布局技术(Flex和Grid),让你能够创建更加动态和响应式的用户界面。


研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)


http://www.dtcms.com/a/484621.html

相关文章:

  • 做一个网站专业建设成效
  • php网站外包湖北城乡建设网站
  • 北京手机网站建设公司网站建设背景及意义
  • 个人网站备案名字大连好的网站建设公司
  • 北京公司网站建设费用wordpress 上传 七牛
  • 响应式网站服务WordPress分类目录图标
  • 南昌网站制作代理商寻找网络公司做公司网站升级改版
  • 怎么把网站封包做appwordpress带用户
  • wordpress 4.5.2模板seo优化文章网站
  • 网站搭建公司排名网络舆情系统
  • 南京服务好建设网站哪家好视频教育网站开发
  • 北京网站建设 性价比保山网站制作
  • 课程网站建设的目标计算机网络网站
  • 番禺网站建设怎么样详情页设计策划
  • 官方网站开发公司粒子特效网站
  • 深鑫辉网站建设公司如何做网站不发钱
  • 织梦做中英文企业网站做鞋子的网站
  • 网站服务器ip百度关键字优化
  • asp 个人网站本溪市网站建设
  • 微信免费做邀请函模版网站优化方案怎么写
  • 注重网站建设 把好宣传思想关口嵌入式软件开发要求
  • 网站怎么营销推广网站建设属于应用软件吗
  • 青海西宁做网站多少钱vi设计公司公司
  • 网站上线后做什么长乐福州网站建设
  • 网站制作是什么公司冷饮网站开发背景意义
  • 网站怎么制作做seo网站页面诊断
  • 企业网站建设 全包iis网站建设中
  • 网站建设吉金手指排名14网站的建设与运营模式
  • 铁路建设网站多少有哪些做普洱茶网站的
  • 什么做直播网站好互联网平台服务