目录
旅行App页面效果
本实例是基于lvgl 8.3 和 windows 11 实现的。效果演示👇
文末给出了UI设计参考出处,仅做学习使用,请勿应用于商业!
2.1 打开小红书
下载你喜欢的图片:小红书 - 你的生活指南
2.2 下载图片
下载的图片一般是webp格式,先转换为lvgl支持的png、jpg等格式:Squoosh
2.3 图片格式转换
在本地文件夹内,可以看到前后转换后,图片分辨率发生了变化
2.4 图片转C数据
开始制作满足lvgl格式的c语言数组形式的图片,打开lvgl官方的图片转换网址&选择如下格式:Image Converter — LVGL
2.5 文件存储结构树
下载得到的 avatar.c 文件请直接保存在项目所在路径
2.6 核心代码
打开 lv_circle.c 文件,下面是完整的代码,可复现
void travel_app_ui_design(void)
{
/*
ui屏幕:
- 1. ui屏幕-样式
- 2. ui屏幕-实例
*/
// 1.1 ui屏幕-样式
static lv_style_t ui_bg_style;
lv_style_init(&ui_bg_style);
lv_style_set_bg_color(&ui_bg_style, lv_color_hex(0x000000)); // 设置背景图颜色:黑色
lv_style_set_pad_all(&ui_bg_style, 5); // 设置偏移量
lv_style_set_radius(&ui_bg_style, 25); // 设置圆角值
// 1.1 ui屏幕-实例
lv_obj_t * ui_scr = lv_obj_create(lv_scr_act());
lv_obj_set_size(ui_scr, lv_pct(100), lv_pct(100));
lv_obj_add_style(ui_scr, &ui_bg_style, 0);
lv_obj_set_scrollbar_mode(ui_scr, LV_SCROLL_SNAP_NONE); // 禁止显示滚动条
/*
顶部组件
- 1. 左👈:时间。右👉:GPS、WiFi 、电量
*/
// 2.1.1 状态栏-样式
static lv_style_t status_bar_style;
lv_style_init(&status_bar_style);
lv_style_set_bg_opa(&status_bar_style, 0); // 设置背景图可见度为0 = 不可见
lv_style_set_border_width(&status_bar_style, 0); // 设置边框宽度为0 = 边框隐藏
// 2.1.2 状态栏-实例
lv_obj_t * status_bar = lv_obj_create(ui_scr);
lv_obj_set_height(status_bar, LV_SIZE_CONTENT); // 根据内部字类的大小动态调整<状态栏>高度
lv_obj_set_width(status_bar, lv_pct(90));
lv_obj_add_style(status_bar, &status_bar_style, 0); // 添加状态栏-样式
lv_obj_set_align(status_bar, LV_ALIGN_TOP_MID); // 设置对齐方式为:顶部居中显示(相对于父类)
// 2.2.1 状态栏icon-样式
static lv_style_t status_icon_style;
lv_style_init(&status_icon_style);
lv_style_set_text_color(&status_icon_style, lv_color_hex(0xffffff));
// 2.2.2 状态栏icon-实例: left-icon
lv_obj_t * status_time_icon = lv_label_create(status_bar);
lv_label_set_text(status_time_icon, "20:05");
lv_obj_add_style(status_time_icon, &status_icon_style, 0);
lv_obj_align_to(status_time_icon, status_bar, LV_ALIGN_TOP_LEFT, 0, 0);
// 2.2.3 状态栏icon-实例: right-icons
lv_obj_t * status_battery_icon = lv_label_create(status_bar);
lv_label_set_text(status_battery_icon, LV_SYMBOL_BATTERY_3); // 右3:电源 icon
lv_obj_add_style(status_battery_icon, &status_icon_style, 0);
// 👇基于父类的对齐方式:顶部右侧
lv_obj_align_to(status_battery_icon, status_bar, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_obj_t * status_wifi_icon = lv_label_create(status_bar);
lv_label_set_text(status_wifi_icon, LV_SYMBOL_WIFI); // 右2:WiFi icon
lv_obj_add_style(status_wifi_icon, &status_icon_style, 0);
// 👇基于<电源 icon>的对齐方式:水平(x)轴方向往左偏移 10px(像素)
lv_obj_align_to(status_wifi_icon, status_battery_icon, LV_ALIGN_OUT_LEFT_MID, -10, 0);
lv_obj_t * status_gps_icon = lv_label_create(status_bar);
lv_label_set_text(status_gps_icon, LV_SYMBOL_GPS); // 右1:GPS icon
lv_obj_add_style(status_gps_icon, &status_icon_style, 0);
// 👇基于<Wifi icon>的对齐方式:水平(x)轴方向往左偏移 10px(像素)
lv_obj_align_to(status_gps_icon, status_wifi_icon, LV_ALIGN_OUT_LEFT_MID, -10, 0);
/*
标题组件
- 1.标题
- 2.副标题
*/
// 3.1.1 标题区域-样式
static lv_style_t title_area_style;
lv_style_init(&title_area_style);
lv_style_set_bg_opa(&title_area_style, 0);
lv_style_set_border_opa(&title_area_style, 0);
// 3.1.2 主标题内容-样式
static lv_style_t title_style;
lv_style_init(&title_style);
lv_style_set_bg_opa(&title_style, 0);
lv_style_set_text_font(&title_style, &lv_font_montserrat_16); // 字体设置
lv_style_set_text_color(&title_style, lv_color_hex(0xffffff)); // 字体颜色设置
// 3.1.3 副标题内容-样式
static lv_style_t subtitle_style;
lv_style_init(&subtitle_style);
lv_style_set_text_font(&subtitle_style, &lv_font_montserrat_12);
lv_style_set_text_color(&subtitle_style, lv_color_hex(0x313247));
lv_style_set_bg_opa(&subtitle_style, 0);
// 3.2.1 标题文本区域-实例
lv_obj_t * title_area = lv_obj_create(ui_scr);
lv_obj_set_size(title_area, lv_pct(90), lv_pct(20));
lv_obj_set_align(title_area, LV_ALIGN_TOP_MID);
lv_obj_set_y(title_area, lv_pct(10));
lv_obj_add_style(title_area, &title_area_style, 0);
lv_obj_set_scrollbar_mode(title_area, LV_SCROLL_SNAP_NONE); // 禁止显示滚动条
// 3.2.2 主标题-实例
lv_obj_t * title_content = lv_label_create(title_area); // 主标题
lv_label_set_text(title_content, "\t\tAwait a day, I want\nto take you to the seaside.");
lv_obj_add_style(title_content, &title_style, 0);
lv_obj_center(title_content); // 主标题居中显示(相对于父类)
// 3.2.3 副标题-实例
lv_obj_t * subtitle_content = lv_label_create(title_area); // 副标题
lv_label_set_text(subtitle_content, "Can it be today?");
lv_obj_add_style(subtitle_content, &subtitle_style, 0);
// 👇副标题相对于主标题向下垂直移动 标题区域高度的20% px
lv_obj_align_to(subtitle_content, title_content, LV_ALIGN_OUT_BOTTOM_MID, 0, lv_pct(20));
/*
状态贴图
- 1. 版面图-样式
- 2. 版面图-实例
*/
// 4.1.1 版面图-样式
static lv_style_t banner_style;
lv_style_init(&banner_style);
lv_style_set_border_opa(&banner_style, 0);
// 4.2.1 版面图区域-实例
lv_obj_t * banner_area = lv_obj_create(ui_scr);
lv_obj_add_style(banner_area, &banner_style, 0);
lv_obj_set_height(banner_area, lv_pct(40));
lv_obj_set_width(banner_area, lv_pct(90));
lv_obj_align(banner_area, LV_ALIGN_CENTER, 0, 0);
// 👇设置滚动条隐藏
lv_obj_set_scrollbar_mode(banner_area, LV_SCROLL_SNAP_NONE);
// 4.2.2 版面图-实例
LV_IMG_DECLARE(banner_01); // 声明版面图
lv_obj_t * banner_img = lv_img_create(banner_area);
lv_img_set_src(banner_img, &banner_01);
lv_obj_center(banner_img); // 设置居中显示
/*
开始按钮
- 1. 按钮-样式
- 2. 按钮-实例
*/
// 5.1.1 按钮-样式
static lv_style_t start_btn_style;
lv_style_init(&start_btn_style);
lv_style_set_bg_color(&start_btn_style, lv_color_hex(0x746df3));
lv_style_set_width(&start_btn_style, lv_pct(90));
lv_style_set_height(&start_btn_style, lv_pct(8));
lv_style_set_align(&start_btn_style, LV_ALIGN_CENTER);
// 5.2.1 按钮-实例
lv_obj_t * start_btn = lv_btn_create(ui_scr);
lv_obj_add_style(start_btn, &start_btn_style, 0);
lv_obj_set_y(start_btn, lv_pct(33));
// 5.2.2 按钮文本-实例
lv_obj_t * start_btn_content = lv_label_create(start_btn);
lv_label_set_text(start_btn_content, "Start your journey");
lv_obj_center(start_btn_content);
// 6.1.1 底部装饰-样式
lv_style_t bottom_btn_style;
lv_style_init(&bottom_btn_style);
lv_style_set_bg_color(&bottom_btn_style, lv_color_hex(0xffffff));
lv_style_set_radius(&bottom_btn_style, lv_pct(1));
lv_style_set_shadow_color(&bottom_btn_style, lv_color_hex(0xffffff));
// 6.2.1 底部装饰-实例
lv_obj_t * bottom_btn = lv_btn_create(ui_scr);
lv_obj_add_style(bottom_btn, &bottom_btn_style, 0);
lv_obj_set_size(bottom_btn, lv_pct(34), 3);
lv_obj_align_to(bottom_btn, ui_scr, LV_ALIGN_BOTTOM_MID, 0, -10);
}
/*
- 如果图片格式在前面没有设置好,这里可以设置图片的缩放比,让头像图片显示在父类框里更加合理
*/
// 获取原始图像的宽度和高度
const lv_img_dsc_t * img_dsc = lv_img_get_src(banner_img);
uint32_t img_w = img_dsc->header.w;
uint32_t img_h = img_dsc->header.h;
/*
- 计算缩放比例,保持宽高比。
- 此处为简单的实现,没有使用算法优化
*/
uint32_t new_w, new_h;
float scale = LV_MIN((float)size / img_w, (float)size / img_h);
new_w = img_w * scale;
new_h = img_h * scale;
lv_img_set_zoom(banner_img, new_w*0.5); // 设置图像的缩放级别,new_w*0.5的值可以自己调整奥~
lv_img_set_antialias(banner_img, true); /* 启用抗锯齿 */
lv_obj_center(banner_img); // 在父类内部居中显示
恭喜🎉你看到了这里,快去动手试试吧~
参考文献:
1 - UI设计灵感:即时设计 - 可实时协作的专业 UI 设计工具
2 - windows颜色提取工具:使用 Color Picker 颜色选择器,瞬间拾取想要的颜色代码
3 - 颜色选择:HTML Color Codes
4 - 图片显示:LVGL移植和图片显示_lvgl 显示图片-CSDN博客
5 - LVGL8.3安装教程:LVGL在VScode中安装模拟器运行配置笔记教程_vscode lvgl-CSDN博客
6 - LVGL通用安装教程:关于用windows搭建lvgl_port_pc_vscode(V9)时碰到的一些问题_windows lvgl-CSDN博客