旅行App UI设计:基于LVGL 8.3与Windows 11的复刻

目录

旅行App页面效果

​编辑

2.1 打开小红书

2.2 下载图片

2.3 图片格式转换

2.4 图片转C数据

2.5 文件存储结构树

2.6 核心代码

参考文献:


旅行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博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值