图标APP UI设计:基于LVGL8.3与Windows11的复刻

目录

图标APP效果

5.1 字体下载

5.2 字体转C数组

5.3 配置字体文件

5.3.1 系统库文件声明

5.3.2 项目库里声明

5.4 图片下载

5.5 图片转换

5.7 项目说明

5.8 核心代码

5.8.1 c文件

5.8.2 头文件

5.9 页面切换

参考文献

图标APP效果

本实例是基于lvgl 8.3 和 windows 11 和老的项目重构的。效果演示👇

emmm~,最近有点事情拖更拉,代码是上周写的,教程是这周做的,争取这周再出一个有用的教程奥~

本教程所用素材来源于互联网,仅作学习使用。Flex布局请参考官网教程奥~

5.1 字体下载

在本次demo中,所用的字体大多来源于作者本作下载的字体奥~

阿里巴巴字体库:iconfont-阿里巴巴矢量图标库

软糖初恋体:作者自己购买的奥~不能用于商业,就不放啦~

请跟随👇图的顺序下载字体,剩余的字体请按照一样的顺序下载奥~

接着,把下载好的字体先解压放在一个文件里,一会儿有用奥!
1.确保提取的字体文件格式为:.ttf or .woff
2.如果不是,请参考<参考文献>提供的字体格式转换网址

5.2 字体转C数组

在之前的教程里并没有说明为什么是C数组而不是二进制bin文件,后者占用更小更快。

选择C数组是因为不需要声明存储位置,读取比较方便。

开始转换前,要确保自己上传的字体支持哪些 Range(编码范围) or Symbols(符号)

字体范围查询页:https://voq.me/character-map/

很好,你已经打开了对吧,开始😊 

- 👈 上角 SELECT FONT -> 用来选择本地的字体文件的
- 👈 侧绿色 -> 显示的就是该字体包含的符号范围
- 👉 ARIAL -> 字体名称
- 👉 BOLD -> 字体粗细 -> 加粗

举个栗子,在Font Card页面的Banner区域,包含👇文字: 

我们该如何定义文字在人类文明史上的分量,又该如何延续这一份传承千年的永恒。
是的,简单的两个字就能够书写出一个人的情感,乃至一个国家的兴衰历史。
在过去,文化交流通过简单的口述、轻薄的纸笔记载。
今天,文化的承载依托于互联网在世界各地传播。
没错!文字是有力量的,它不仅仅是一笔一划,是所有寄托于精神的人民的呐喊。

跟着我,先看👀下载的字体是否包含这些文字符号,如👇图所示

偷个懒😄,使用 软糖初恋体.ttf 测试 -> 兼容很好,转换的时候要注意填写 Symbol奥~ 

- 左侧区域往下看,发现这个字体的(Range)范围是:0x0000-0x9661
- Range填写:0x0004-0x9661

👆的Range前几位是空的,有概率导致符号不显示。主要是会导致中文逗号不显示。

"如果你知道是为什么,欢迎留言、私信教导我,谢谢🙏" 

LVGL官方字体转换工具: <https://lvgl.io/tools/fontconverter>

用👆这个链接,下面的图一是方法一 

推荐使用下面👇这个方法二,可以减少字体占用大小 

 太厉害啦你!恭喜🎉!你已经能够独自将这些字体文件 -> 转换为c语言数组。

5.3 配置字体文件

在过往的👆教程里,使用了内置的字体声明方法,这次把两种方式都讲解下~

5.3.1 系统库文件声明

将转换好的字体文件复制到:lvgl\src\font\ 路径下,如👇图所示

在 lv_font.h 和 lv_conf.h 中声明,如👇图所示(黄色区域字体下载链接放在参考文献板块啦~)

第一次加代码,最担心的就是代码写在哪里! 

 答:可以打开文件往下看,看看系统内置的代码是怎么写的,放在它们的下面👇就好啦~
     - 黄色框:系统内置字体且已经声明了
     - 白色框:作者下载的字体奥~,目前只启用了第二行的16号字体,其它没启用,是灰色的奥~

调用方法,就像👇图里所示的写法,在对应的 label 控件里进行声明奥~

5.3.2 项目库里声明

方法二和👆的类似奥,为了方便起见,可以直接把字体文件放到项目根目录下

使用 LV_FONT_DECLARE 进行声明即可,如👇图所示。

注意⚠️:在本作者的demo里,使用的是内置文件的方式,前文已经说过啦。

~ 所以添加进来发现读取不到的话: 就是未声明(undeclared)问题

方法1:重新打开VS Code
方法2:在Terminal 里面 重新 Cmake

5.4 图片下载

在Font Card页面:图片来源于Alimama:iconfont-阿里巴巴矢量图标库

下面👇这张图里面有 Font Card页面 的Banner(版面)图奥~

下面👇这张是 Icon Card 页面的Banner图奥~

5.5 图片转换

让我们继续趴~,先打开谷歌压缩:Squoosh

1.转换大小,2.转换格式

使用方法,参考教程👉:旅行App UI设计:基于LVGL 8.3与Windows 11的复刻_使用lvgl编写的app-CSDN博客

下面👇先转换下图片大小,看看👀吧~ 

 

要用到LVGL官方转换工具:Image Converter — LVGL

和👀前面字体转C数组一样的😊,还可以选择转为bin文件(二进制)奥~

因为拖更很久啦,这一块是重点,先补上!!!😊

除了普通的图片外,在LVGL里面还内置了一些Symbol符号字体,看看👇的图。

使用也是很简单奥~以本次demo里用到的WIFI Symbol(符号) 为栗子。请看👇的图

那么,就有人好奇🤔了,怎么使用第三方的,可以参考👇的网站。

FontAwesome是官方内置的Symbol来源,就不演示啦,后续会出一期基础的LVGL的教程

  1. 阿里妈妈的图标库:iconfont-阿里巴巴矢量图标库

  2. Font Awesome:Font Awesome

  3. 其实谷歌et. al:https://fonts.google.com/icons

可以直接在首页搜索你需要的图标 or 进入图标库 查看精选图标。

看我教程👀的小伙伴们,肯定都是又好看又聪明,我就不多说啦~

下面👇这里,要注意点击加入购物车后,点击右上角的购物车图标,跟随👇的图文教程继续趴~

记得要选择你自己的项目奥,没有的话就新建一个。

现在,一起来看看在本次demo的图标是如何变成可以用的Symbo符号的。

贴一个官网教程的链接:Fonts(字体) — 百问网LVGL中文教程文档 文档

下载👇对应的字体包,然后跟着我解压一下,再提取其中的ttf文件

提取完字体,为了后续便于辨认,我换了个名字,如👇所示。

接着,要到关键步骤啦,聪明的你已经想到之前字体是如何转为内置的C数组文件的,其实步骤一样!看好啦👀

为了大家的便利,再贴一次字体转换网站:Font Converter — LVGL

设置还是很简单的,上面👆设置下"名称、大小、分辨率(8bit最清晰,1bit最模糊)、输出格式(C数组)"

然后开始逐个复制👇需要的图标的16进制的 Unicode 编码~

直接把对应的编码转换好贴出来,小伙伴们可以比对下。其它是去掉了前面的 &# 和 最后的 ;  最后开头加上 0(16进制编码是0x开始的奥)。

要注意2个图标的进制码分隔,要使用英文逗号🔍

0xe600, 0xe688, 0xe627, 0xe8b1

有了前面👆的铺垫,符号字体已经生成啦,记得放到你的项目里,如👇所示。

内容是有点多的,文件也乱。可以用VS Code去搜索🔍文件名,很方便的!

接着,最关键的来啦,演示👀如何定义与使用。

是不是有人开始头晕想去摸鱼了,都看到这里了,还能让你带着困惑复刻demo,那就是我的不对了,安排!👀下面👇。

打开编码转换网站,Unicde -> Hex code(utf-8):UTF-8 Tool

0xe600 -> \xEE\x98\x80

第一次我看到👆的编码转换,大脑🧠已经失控了。后来看👀 了AI的解释。因为Hex的字符,在LVGL里面需要加上 \x 保持16进制的形式读取单个字符。

好啦,看到这里肯定已经懂啦,那就看看如何使用这个Symbol图像,看看👀代码。👇

终于,把核心部分都讲完啦~,如果看不懂,可以随意留言。有错误的地方,欢迎👏指教。 

5.7 项目说明

👆已经完成了demo的初步准备,请你耐心阅读下项目说明,以便于顺利复现与理解项目

/*
    分辨率:2:1
        #  define SDL_HOR_RES     1200
        #  define SDL_VER_RES     600
    Flex 布局
        👇设置flex分配比例为0,后面还会分配一个子类比例为1。
            - 相当于这里先设置高度,后面同父类的子类的高度就会占用剩余的父类空间。
        以计算宽度为例:
            - 父类  -> app_scr:[########]
            - 子类1 -> ui.header_container(flex_grow = 0):[###] -> 用户定义宽度
            - 子类2 -> font_card_area(flex_grow = 1): [########] - [###] = [#####] -> 系统自动计算宽度
    树状结构:
        ui.screen_app
            - ui.header_container
                - ui.status_bar
                - ui.content_switcher
            - font_card_area
                - ui.font_banner
                - using loop to create font_card_area
                    - ui.daoli_font_card
                    - ui.fangyuan_font_card
                    - ui.lingdong_font_card
                    - ui.dongfang_font_card
                    - ui.shuhei_font_card
                    - ui.ruantang_font_card
            - icon_card_area
                - ui.icon_banner
                - some_card_display
                    - using loop to create icon_card_area
    代码编写顺序:
        - stylesheet(static lv_style_t obj_style)
        - instance(lv_obj_t * obj)
*/

5.8 核心代码

5.8.1 c文件

打开 lv_font_icon_app.c 文件,👇是完整的代码,可复现

在👇代码中,新代码或API都会在首次给出注释。 

/**
 * @file lv_font_icon_app
 *
 */
​
/*********************
 *      INCLUDES
 *********************/
#include "lv_font_icon_app.h"
​
// 声明下面👇定义的函数
static void event_handler(lv_event_t *e);
static void lv_icon_card_page_init(void);
static void lv_font_card_page_init(void);
​
// 状态变量:记录 字体/图标库 是否可见
static bool font_gallery_visible = false;
static bool icon_gallery_visible = false;
​
void lv_style_init_bg_color(lv_style_t *style, lv_color_t color)
{
    lv_style_init(style);                  // 初始化样式
    lv_style_set_bg_color(style, color);   // 设置背景颜色
}
​
void lv_ui_stylesheet(void)
{
    lv_style_init(&style.app_scr_style);
    lv_style_set_bg_color(&style.app_scr_style, APP_BG_COLOR);
    lv_style_set_pad_all(&style.app_scr_style, 0);      // 👈设置对象内部所有填充为0
    lv_style_set_border_width(&style.app_scr_style, 0); // 👈设置边框宽度为0
​
    lv_style_init(&style.app_header_style);
    lv_style_set_bg_color(&style.app_header_style, HEADER_BG_COLOR);
    lv_style_set_pad_all(&style.app_header_style, 0);
    lv_style_set_border_width(&style.app_header_style, 0);
    lv_style_set_radius(&style.app_header_style, 0);    // 👈设置圆角为0
    lv_style_set_flex_grow(&style.app_header_style, 0); // 👈设置flex增长系数为0
​
    lv_style_init(&style.status_bar_style);
    lv_style_set_bg_opa(&style.status_bar_style, 0);
    lv_style_set_border_width(&style.status_bar_style, 0);
    lv_style_set_radius(&style.status_bar_style, 0);
​
    lv_style_init(&style.status_icon_style);
    lv_style_set_text_color(&style.status_icon_style, WHITE_COLOR);
​
    lv_style_init(&style.content_switcher_style);
    lv_style_set_bg_opa(&style.content_switcher_style, 0);
    lv_style_set_border_width(&style.content_switcher_style, 0);
    lv_style_set_radius(&style.content_switcher_style, 0);
    lv_style_set_pad_all(&style.content_switcher_style, 0);
    lv_style_set_pad_left(&style.content_switcher_style, 20);
    lv_style_set_pad_right(&style.content_switcher_style, 20);
​
    lv_style_init(&style.page_sw_btn_txt_style);
    lv_style_set_text_font(&style.page_sw_btn_txt_style, &lv_font_alimama_dongfang_16); // 👈设置文本字体
    lv_style_set_bg_opa(&style.page_sw_btn_txt_style, LV_OPA_TRANSP);     // 👈设置背景透明
    lv_style_set_border_opa(&style.page_sw_btn_txt_style, LV_OPA_TRANSP); // 👈设置按钮边框隐藏
    lv_style_set_shadow_opa(&style.page_sw_btn_txt_style, LV_OPA_TRANSP); // 👈设置阴影效果隐藏
​
    lv_style_init(&style.banner_style);
    lv_style_set_bg_opa(&style.banner_style, 0);
    lv_style_set_border_opa(&style.banner_style, 0);
    lv_style_set_clip_corner(&style.banner_style, true); // 👈启用裁剪,子类超出部分会被屏蔽
    lv_style_set_pad_all(&style.banner_style, 0);
    lv_style_set_text_color(&style.banner_style, BANNER_FONT_COLOR);
    lv_style_set_text_line_space(&style.banner_style, 10); // 👈设置行间距
​
    lv_style_init(&style.font_card_items_style);
    lv_style_set_pad_all(&style.font_card_items_style, 0);
    lv_style_set_bg_opa(&style.font_card_items_style, 0);
    lv_style_set_border_width(&style.font_card_items_style, 0);
    lv_style_set_pad_row(&style.font_card_items_style, 50);
​
    lv_style_init(&style.font_card_item_style);
    lv_style_set_bg_color(&style.font_card_item_style, WHITE_COLOR);
    lv_style_set_pad_all(&style.font_card_item_style, 0);
    lv_style_set_radius(&style.font_card_item_style, 5);
    lv_style_set_border_opa(&style.font_card_item_style, 0);
    lv_style_set_pad_right(&style.font_card_item_style, 15);
    lv_style_set_pad_left(&style.font_card_item_style, 15);
    lv_style_set_pad_bottom(&style.font_card_item_style, 15);
    lv_style_set_pad_top(&style.font_card_item_style, 24);
​
    lv_style_init(&style.icon_card_items_style);
    lv_style_set_pad_all(&style.icon_card_items_style, 0);
    lv_style_set_bg_opa(&style.icon_card_items_style, 0);
    lv_style_set_border_width(&style.icon_card_items_style, 0);
    lv_style_set_pad_row(&style.icon_card_items_style, 50);     // 👈设置行间距
​
    lv_style_init(&style.icon_card_item_style);
    lv_style_set_bg_color(&style.icon_card_item_style, WHITE_COLOR);
    lv_style_set_pad_all(&style.icon_card_item_style, 0);
    lv_style_set_radius(&style.icon_card_item_style, 5);
    lv_style_set_border_opa(&style.icon_card_item_style, 0);
​
    // 👇通过自定义函数初始化背景颜色
    lv_style_init_bg_color(&style.icon_card_item1_style, ICON_CARD_ITEM_COLOR1);
    lv_style_init_bg_color(&style.icon_card_item2_style, ICON_CARD_ITEM_COLOR2);
    lv_style_init_bg_color(&style.icon_card_item3_style, ICON_CARD_ITEM_COLOR3);
    lv_style_init_bg_color(&style.icon_card_item4_style, ICON_CARD_ITEM_COLOR4);
    lv_style_init_bg_color(&style.icon_card_item5_style, ICON_CARD_ITEM_COLOR5);
    lv_style_init_bg_color(&style.icon_card_item6_style, ICON_CARD_ITEM_COLOR6);
​
    lv_style_init(&style.icon_card_txt_color_style);
    lv_style_set_text_color(&style.icon_card_txt_color_style, ICON_CARD_TXT_COLOR);
​
    lv_style_init(&style.icon_card_icon_color_style);
    lv_style_set_text_color(&style.icon_card_icon_color_style, BLACK_COLOR);
}
​
​
void lv_font_icon_app(void)
{
    lv_ui_stylesheet();     // 样式表初始化
    
    /*-----------------------FANQIELAN:1-屏幕实例--------------------------------*/
​
    ui.screen_app = lv_obj_create(lv_scr_act());
    lv_obj_set_size(ui.screen_app, lv_pct(100), lv_pct(100)); // 👈设置大小为父类的100%
    lv_obj_set_flex_flow(ui.screen_app, LV_FLEX_FLOW_COLUMN); //  👈设置垂直方向换行Flex布局
    // 👇子类对象居中显示
    lv_obj_set_flex_align(ui.screen_app, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_obj_add_style(ui.screen_app, &style.app_scr_style, 0);      // 👈添加样式
    lv_obj_set_scroll_dir(ui.screen_app, LV_DIR_VER);              // 👈设置滚动为垂直方向上下滚动
    lv_obj_set_scrollbar_mode(ui.screen_app, LV_SCROLL_SNAP_NONE); // 👈设置滚动条隐藏
​
​
    /*-----------------------FANQIELAN:2-头部区域--------------------------------*/
​
    ui.header_container = lv_obj_create(ui.screen_app);
    lv_obj_set_size(ui.header_container, lv_pct(100), 135);                 // 👈尺寸:1200 * 135 ☑️
    lv_obj_add_style(ui.header_container, &style.app_header_style, 0);
    lv_obj_set_align(ui.header_container, LV_ALIGN_TOP_MID);                // 👈设置顶部居中对齐
    lv_obj_set_scrollbar_mode(ui.header_container, LV_SCROLLBAR_MODE_OFF);  // 👈设置滚动条禁用
​
    /*-----------------------FANQIELAN:2.1 状态栏--------------------------------*/
​
    // 状态栏:左👈:信号图标。中间:时间。右👉:GPS、WiFi 、电量
    ui.status_bar = lv_obj_create(ui.header_container);
    lv_obj_set_size(ui.status_bar, lv_pct(100), 40); // 👈尺寸:1200 * 40 ☑️
    lv_obj_set_scrollbar_mode(ui.status_bar, LV_SCROLLBAR_MODE_OFF);
    lv_obj_add_style(ui.status_bar, &style.status_bar_style, 0);
​
    // 2.2.1 状态栏👈信号icon
    ui.status_signal_icon = lv_label_create(ui.status_bar);
    lv_obj_set_style_text_font(ui.status_signal_icon, &lv_icon_gallery_bar_icons_16, 0);
    lv_label_set_text(ui.status_signal_icon, LV_SYMBOL_SIGNAL_ICON);
    lv_obj_add_style(ui.status_signal_icon, &style.status_icon_style, 0);
    lv_obj_align(ui.status_signal_icon, LV_ALIGN_LEFT_MID, 0, 0);
​
    // 2.2.2 状态栏👈文本
    ui.status_signal_text = lv_label_create(ui.status_bar);
    // 👇设置icon字体
    lv_obj_set_style_text_font(ui.status_signal_text, &lv_icon_gallery_bar_font_14, 0);
    lv_label_set_text(ui.status_signal_text, "中国广电");
    lv_obj_add_style(ui.status_signal_text, &style.status_icon_style, 0);
    lv_obj_align_to(ui.status_signal_text, ui.status_signal_icon, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
​
    // 2.2.3 状态栏⌛️icon
    ui.status_time_icon = lv_label_create(ui.status_bar);
    lv_label_set_text(ui.status_time_icon, "11:11 AM");
    lv_obj_add_style(ui.status_time_icon, &style.status_icon_style, 0);
    lv_obj_center(ui.status_time_icon);
​
    // 2.2.4.1 状态栏👉电池icon
    ui.status_battery_icon = lv_label_create(ui.status_bar);
    lv_label_set_text(ui.status_battery_icon, "100% \xEF\x89\x80");
    lv_obj_add_style(ui.status_battery_icon, &style.status_icon_style, 0);
    lv_obj_align_to(ui.status_battery_icon, ui.status_bar, LV_ALIGN_TOP_RIGHT, 0, 0);
​
    // 2.2.4.2 状态栏👉无线网络icon
    ui.status_wifi_icon = lv_label_create(ui.status_bar);
    lv_label_set_text(ui.status_wifi_icon, LV_SYMBOL_WIFI);
    lv_obj_add_style(ui.status_wifi_icon, &style.status_icon_style, 0);
    lv_obj_align_to(ui.status_wifi_icon, ui.status_battery_icon, LV_ALIGN_OUT_LEFT_MID, -10, 0);
​
    // 2.2.4.3 状态栏:👉定位icon
    ui.status_gps_icon = lv_label_create(ui.status_bar);
    lv_label_set_text(ui.status_gps_icon, LV_SYMBOL_GPS);
    lv_obj_add_style(ui.status_gps_icon, &style.status_icon_style, 0);
    lv_obj_align_to(ui.status_gps_icon, ui.status_wifi_icon, LV_ALIGN_OUT_LEFT_MID, -10, 0);
​
    /*-----------------------FANQIELAN:2.2-页面选择按钮区域--------------------------------*/
​
    ui.content_switcher = lv_obj_create(ui.header_container);
    lv_obj_set_size(ui.content_switcher, 1160, 65); // 👈设置尺寸
    lv_obj_set_flex_grow(ui.content_switcher, 0);   // 👈设置flex增长系数为0
    lv_obj_set_flex_flow(ui.content_switcher, LV_FLEX_FLOW_ROW_WRAP);   // 设置flex布局为行且自动换行
    lv_obj_set_flex_align(ui.content_switcher, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_SPACE_EVENLY);
    lv_obj_set_align(ui.content_switcher, LV_ALIGN_BOTTOM_LEFT);
    lv_obj_add_style(ui.content_switcher, &style.content_switcher_style, 0);
​
    // 2.3.1 字体库
    ui.font_gallery_btn = lv_btn_create(ui.content_switcher);
    lv_obj_t *font_gallery_btn_text = lv_label_create(ui.font_gallery_btn);
    lv_label_set_text(font_gallery_btn_text, "Font Gallery");
    lv_obj_center(font_gallery_btn_text);
    lv_obj_add_style(ui.font_gallery_btn, &style.page_sw_btn_txt_style, 0);
    // 👇添加按钮事件
    lv_obj_add_event_cb(ui.font_gallery_btn, event_handler, LV_EVENT_ALL, NULL);
​
    // 2.3.2 图标库
    ui.icon_gallery_btn = lv_btn_create(ui.content_switcher);
    lv_obj_t *icon_gallery_btn_text = lv_label_create(ui.icon_gallery_btn);
    lv_label_set_text(icon_gallery_btn_text, "Icon Gallery");
    lv_obj_center(icon_gallery_btn_text);
    lv_obj_add_style(ui.icon_gallery_btn, &style.page_sw_btn_txt_style, 0);
    lv_obj_add_event_cb(ui.icon_gallery_btn, event_handler, LV_EVENT_ALL, NULL);
​
    /*-----------------------FANQIELAN:3-字体卡片区域--------------------------------*/
    lv_font_card_page_init();
​
    /*-----------------------FANQIELAN:4-图标卡片区域--------------------------------*/
    lv_icon_card_page_init();
}
​
static void event_handler(lv_event_t *e) {
​
    lv_event_code_t code = lv_event_get_code(e);    // 👈获取事件的代码类型
    lv_obj_t *target = lv_event_get_target(e);      // 👈获取触发事件的目标对象
​
    if (code == LV_EVENT_CLICKED) {
        // 👆检查事件是否为点击事件
        lv_obj_t *label = lv_obj_get_child(target, 0);  // 👈获取label标签🏷
        const char *text = lv_label_get_text(label);    // 👈获取对应的文本内容
​
        if (strcmp(text, "Font Gallery") == 0) {    
            // 👆如果是点击切换字体页面按钮
            LV_LOG_USER("Switch to Font Page");
            if (&ui.icon_card_area != NULL && &ui.font_card_area != NULL) {
                lv_obj_add_flag(ui.icon_card_area, LV_OBJ_FLAG_HIDDEN);     // 👈隐藏图标页面
                lv_obj_clear_flag(ui.font_card_area, LV_OBJ_FLAG_HIDDEN);   // 👈显示字体页面
            }
        }
        else if (strcmp(text, "Icon Gallery") == 0) {
            // 👆如果是点击切换图标页面按钮
            LV_LOG_USER("Switch to Icon Page");
            if (&ui.icon_card_area != NULL && &ui.font_card_area != NULL) {
                lv_obj_add_flag(ui.font_card_area, LV_OBJ_FLAG_HIDDEN);     // 👈隐藏字体页面
                lv_obj_clear_flag(ui.icon_card_area, LV_OBJ_FLAG_HIDDEN);   // 👈显示图标页面
            }
        }
    }
}
​
​
static void lv_font_card_page_init(void)
{
    LV_LOG_USER("Initializing Font Card Page");  // 👈初始化页面打印信息
​
    ui.font_card_area = lv_obj_create(ui.screen_app);
    lv_obj_set_pos(ui.font_card_area, 0, 135);
    lv_obj_set_size(ui.font_card_area, 1160, 465);   
    lv_obj_set_scrollbar_mode(ui.font_card_area, LV_SCROLLBAR_MODE_ACTIVE);  // 👈设置当滚动页面 -> 显示滚动条
    lv_obj_set_scroll_dir(ui.font_card_area, LV_DIR_VER);
    lv_obj_set_flex_grow(ui.font_card_area, 0);  // 👈防止占据空间
​
    // 3.1.1 字体库内部子项
    ui.font_card_container = lv_obj_create(ui.font_card_area);
    lv_obj_set_size(ui.font_card_container, lv_pct(100), 1100);
    lv_obj_align_to(ui.font_card_container, ui.font_card_area, LV_ALIGN_TOP_MID, 0, 50);
    lv_obj_add_style(ui.font_card_container, &style.font_card_items_style, 0);
    lv_obj_set_flex_flow(ui.font_card_container, LV_FLEX_FLOW_ROW_WRAP);
    lv_obj_set_flex_align(ui.font_card_container, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START);
​
    // 3.1.2 字体库版面图
    ui.font_banner = lv_obj_create(ui.font_card_container);
    lv_obj_set_size(ui.font_banner, 1160, 230);
    lv_obj_set_style_radius(ui.font_banner, 8, 0);  // 👈设置圆角值为8
    lv_obj_set_scrollbar_mode(ui.font_banner, LV_SCROLL_SNAP_NONE);
    lv_obj_add_style(ui.font_banner, &style.banner_style, 0);
​
    ui.font_banner_img = lv_img_create(ui.font_banner);
    lv_img_set_src(ui.font_banner_img, &lv_font_banner_img);
    lv_obj_set_size(ui.font_banner_img, 1160, 230);
    lv_obj_center(ui.font_banner_img);
​
    ui.banner_content = lv_label_create(ui.font_banner);
    lv_obj_set_style_text_font(ui.banner_content, &lv_font_banner_ruantang_16, 0);
    const char *banner_text_01 = "我们该如何定义文字在人类文明史上的分量,又该如何延续这一份传承千年的永恒。\n";
    const char *banner_text_02 = "是的,简单的两个字就能够书写出一个人的情感,乃至一个国家的兴衰历史。\n";
    const char *banner_text_03 = "在过去,文化交流通过简单的口述、轻薄的纸笔记载。\n";
    const char *banner_text_04 = "今天,文化的承载依托于互联网在世界各地传播。\n";
    const char *banner_text_05 = "没错!文字是有力量的,它不仅仅是一笔一划,是所有寄托于精神的人民的呐喊。";
    char banner_story[512];
    strcpy(banner_story, banner_text_01);
    strcat(banner_story, banner_text_02);
    strcat(banner_story, banner_text_03);
    strcat(banner_story, banner_text_04);
    strcat(banner_story, banner_text_05);
    lv_label_set_text(ui.banner_content, banner_story);
    lv_obj_align(ui.banner_content, LV_ALIGN_TOP_LEFT, 40, 70);
​
    // 3.1.3 展示字体子项
    ui.font_card_items = lv_obj_create(ui.font_card_container);
    lv_obj_set_size(ui.font_card_items, 1120, LV_SIZE_CONTENT);
    lv_obj_set_flex_flow(ui.font_card_items, LV_FLEX_FLOW_ROW_WRAP);
    lv_obj_set_flex_align(ui.font_card_items, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_SPACE_EVENLY);
    lv_obj_set_scrollbar_mode(ui.font_card_items, LV_SCROLL_SNAP_NONE);
    lv_obj_add_style(ui.font_card_items, &style.icon_card_item_style, 0);
​
    // 字体引用数组
    const lv_font_t *font_family_name[] = {
        &lv_font_alimama_fangyuan_16,
        &lv_font_alimama_daoli_16,
        &lv_font_alimama_lingdong_16,
        &lv_font_alimama_dongfang_16,
        &lv_font_alimama_shuhei_16,
        &lv_font_ruantang_16
    };
​
    // 图片引用数组
    const lv_img_dsc_t *font_img_array[] = {
        &lv_img_fangyuan,
        &lv_img_daoli,
        &lv_img_lingdong,
        &lv_img_dongfang,
        &lv_img_shuhei,
        &lv_img_ruantang
    };
​
    // 卡片字体名称数组
    const char *font_card_items_name[] = {
        "方圆体(Fangyuan Font)",
        "刀栗体(Daoli Font)",
        "Lingdong Ti(Agile Font)",
        "东方大楷(Dongfang Font)",
        "数栗体(Shuhei Font)",
        "软糖初恋体(Ruantang Font)"
    };
​
    // 循环创建字体卡片
    for (i = 0; i < 6; i++)
    {
        ui.font_card_item = lv_btn_create(ui.font_card_items);
        lv_obj_set_size(ui.font_card_item, 360, 291);
        lv_obj_add_style(ui.font_card_item, &style.font_card_item_style, 0);
        lv_obj_set_scrollbar_mode(ui.font_card_item, LV_SCROLL_SNAP_NONE);
​
        ui.font_card_img = lv_img_create(ui.font_card_item);
        lv_img_set_src(ui.font_card_img, font_img_array[i]);
        lv_obj_set_size(ui.font_card_img, 330, 178);
        lv_obj_align(ui.font_card_img, LV_ALIGN_TOP_LEFT, 0, 0);
​
        ui.font_card_txt = lv_label_create(ui.font_card_item);
        lv_obj_set_style_text_font(ui.font_card_txt, font_family_name[i], 0);
        lv_label_set_text(ui.font_card_txt, font_card_items_name[i]);
        lv_obj_set_style_text_color(ui.font_card_txt, BLACK_COLOR, 0);
        lv_obj_align(ui.font_card_txt, LV_ALIGN_BOTTOM_LEFT, 0, 0);
        lv_obj_add_style(ui.font_card_txt, &style.font_card_item_style, 0);
    }
}
​
static void lv_icon_card_page_init(void)
{
    LV_LOG_USER("Initializing Icon Card Page"); // 👈初始化页面打印信息
​
    ui.icon_card_area = lv_obj_create(ui.screen_app);
    lv_obj_set_pos(ui.icon_card_area, lv_pct(100), 135);
    lv_obj_set_size(ui.icon_card_area, 1160, 465);
    lv_obj_set_scrollbar_mode(ui.icon_card_area, LV_SCROLLBAR_MODE_ACTIVE);
    lv_obj_set_scroll_dir(ui.icon_card_area, LV_DIR_VER);
    lv_obj_set_flex_grow(ui.icon_card_area, 0);
    lv_obj_add_flag(ui.icon_card_area, LV_OBJ_FLAG_HIDDEN);
​
    // 4.1.1 图标库内部子项
    ui.icon_card_container = lv_obj_create(ui.icon_card_area);
    lv_obj_set_size(ui.icon_card_container, lv_pct(100), LV_SIZE_CONTENT);
    lv_obj_align_to(ui.icon_card_container, ui.icon_card_area, LV_ALIGN_TOP_MID, 0, 50);
    lv_obj_set_flex_flow(ui.icon_card_container, LV_FLEX_FLOW_ROW_WRAP);
    lv_obj_add_style(ui.icon_card_container, &style.icon_card_items_style, 0);
​
    // 4.1.2 图标库版面
    ui.icon_banner = lv_obj_create(ui.icon_card_container);
    lv_obj_set_size(ui.icon_banner, 1116, 230);
    lv_obj_set_style_radius(ui.icon_banner, 8, 0);
    lv_obj_set_scrollbar_mode(ui.icon_banner, LV_SCROLL_SNAP_NONE);
    lv_obj_set_style_bg_color(ui.icon_banner, ICON_CARD_BANNER_COLOR, 0);
    lv_obj_center(ui.icon_banner);
    lv_obj_add_style(ui.icon_banner, &style.banner_style, 0);
​
    ui.icon_banner_img = lv_img_create(ui.icon_banner);
    lv_img_set_src(ui.icon_banner_img, &lv_icon_banner_img);
    lv_obj_set_size(ui.icon_banner_img, 1160, 230);
    lv_obj_center(ui.icon_banner_img);
​
    ui.icon_banner_logo = lv_label_create(ui.icon_banner);
    lv_obj_set_style_text_font(ui.icon_banner_logo, &lv_icon_gallery_banner_logo_30, 0);
    lv_label_set_text(ui.icon_banner_logo, LV_SYMBOL_ZHONGQIU_ICON);
    lv_obj_add_style(ui.icon_banner_logo, &style.status_icon_style, 0);
    lv_obj_align(ui.icon_banner_logo, LV_ALIGN_TOP_LEFT, 30, 30);
​
    // banner_content_title
    ui.icon_banner_title = lv_label_create(ui.icon_banner);
    lv_obj_set_style_text_font(ui.icon_banner_title, &lv_icon_banner_title_font_18, 0);
    lv_label_set_text(ui.icon_banner_title, "阿里妈妈·图标库");
    lv_obj_align_to(ui.icon_banner_title, ui.icon_banner_logo, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
​
    // ui.banner_content
    ui.icon_banner_txt = lv_label_create(ui.icon_banner);
    lv_obj_set_style_text_font(ui.icon_banner_txt, &lv_icon_banner_font_16, 0);
    const char *icon_banner_text_01 = "如果说文字是无形的,那么图标就是它们的具象。\n";
    const char *icon_banner_text_02 = "小时候,画画是随着笔在纸上游走。\n";
    const char *icon_banner_text_03 = "长大后,画画是篆刻在心里却映衬在荧幕里的思念。\n";
    const char *icon_banner_text_04 = "后来,我们学会了在生活中捕捉美好。\n";
    const char *icon_banner_text_05 = "今天,让icon去点亮藏在文字里的美好~";
    char icon_banner_story[512];
    strcpy(icon_banner_story, icon_banner_text_01);
    strcat(icon_banner_story, icon_banner_text_02);
    strcat(icon_banner_story, icon_banner_text_03);
    strcat(icon_banner_story, icon_banner_text_04);
    strcat(icon_banner_story, icon_banner_text_05);
    lv_label_set_text(ui.icon_banner_txt, icon_banner_story);
    lv_obj_align(ui.icon_banner_txt, LV_ALIGN_BOTTOM_LEFT, 40, -26);
​
    // 4.1.3 图标卡片项
    ui.icon_card_items = lv_obj_create(ui.icon_card_container);
    lv_obj_set_size(ui.icon_card_items, 1120, 1200);
    lv_obj_set_flex_flow(ui.icon_card_items, LV_FLEX_FLOW_ROW_WRAP);
    lv_obj_set_flex_align(ui.icon_card_items, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START);
    lv_obj_set_scrollbar_mode(ui.icon_card_items, LV_SCROLL_SNAP_NONE);
    lv_obj_set_style_pad_row(ui.icon_card_items, 35, 0);    // 👈设置行间距
    lv_obj_add_style(ui.icon_card_items, &style.icon_card_item_style, 0);
​
    const char *icon_card_items_name[] = {
        "Emoji",
        "Vegetables",
        "Alphabet",
        "Maritime",
        "Science",
        "All Categories"
    };
​
    // 图标卡片样式
    lv_style_t *icon_card_styles[] = {
        &style.icon_card_item1_style,
        &style.icon_card_item2_style,
        &style.icon_card_item3_style,
        &style.icon_card_item4_style,
        &style.icon_card_item5_style,
        &style.icon_card_item6_style
    };
​
    // 图标卡片字符图片
    const char *icon_card_item_symbols[] = {
        "\xEE\x98\x87", // 笑脸🤣
        "\xEE\x9B\x8D", // 草莓🍓
        "\xEE\x98\x81", // 字母A
        "\xEE\x98\x94", // 海洋的🦀
        "\xEE\xA6\x98", // 科学✈️
        "\xEE\x9B\xA5"  // 分类
    };
​
    // 循环创建图标卡片
    for (i = 0; i < 6; i++)
    {
        // 第一行(6张卡片)
        ui.icon_card_item = lv_btn_create(ui.icon_card_items);
        lv_obj_set_size(ui.icon_card_item, 155, 126);
        lv_obj_center(ui.icon_card_item);
        lv_obj_add_style(ui.icon_card_item, icon_card_styles[i], 0);
​
        ui.item_img_label = lv_label_create(ui.icon_card_item);
        lv_obj_set_style_text_font(ui.item_img_label, &lv_icon_first_line_fonticon_32, 0);
        lv_label_set_text(ui.item_img_label, icon_card_item_symbols[i]);
        lv_obj_align(ui.item_img_label, LV_ALIGN_CENTER, 0, -10);
        lv_obj_add_style(ui.item_img_label, &style.icon_card_icon_color_style, 0);
​
        ui.item_img_symbol = lv_label_create(ui.icon_card_item);
        lv_label_set_text(ui.item_img_symbol, icon_card_items_name[i]);
        lv_obj_set_style_text_font(ui.item_img_symbol, &lv_font_alimama_dongfang_16, 0);
        lv_obj_align_to(ui.item_img_symbol, ui.icon_card_item, LV_ALIGN_BOTTOM_MID, 0, 0);
        lv_obj_add_style(ui.item_img_symbol, &style.icon_card_txt_color_style, 0);
    }
    for (i = 0; i < 2; i++)
    {
        if(i==0){
            for (j = 0; j < 4; j++)
            {
                // 第二行(4张卡片)
                ui.icon_card_item = lv_btn_create(ui.icon_card_items);
                lv_obj_set_size(ui.icon_card_item, 254, 280);
                lv_obj_center(ui.icon_card_item);
                lv_obj_add_style(ui.icon_card_item, icon_card_styles[j], 0);
​
                ui.item_img_label = lv_label_create(ui.icon_card_item);
                lv_obj_set_style_text_font(ui.item_img_label, &lv_icon_first_line_fonticon_32, 0);
                lv_label_set_text(ui.item_img_label, icon_card_item_symbols[j]);
                lv_obj_align(ui.item_img_label, LV_ALIGN_CENTER, 0, -10);
                lv_obj_add_style(ui.item_img_label, &style.icon_card_icon_color_style, 0);
​
                ui.item_img_symbol = lv_label_create(ui.icon_card_item);
                lv_label_set_text(ui.item_img_symbol, icon_card_items_name[j]);
                lv_obj_set_style_text_font(ui.item_img_symbol, &lv_font_alimama_dongfang_16, 0);
                lv_obj_align_to(ui.item_img_symbol, ui.icon_card_item, LV_ALIGN_BOTTOM_MID, 0, 0);
                lv_obj_add_style(ui.item_img_symbol, &style.icon_card_txt_color_style, 0);
            }
        } else {
            for (j = 3; j > -1; j--)
            {
                // 第三行(4张卡片)
                ui.icon_card_item = lv_btn_create(ui.icon_card_items);
                lv_obj_set_size(ui.icon_card_item, 254, 280);
                lv_obj_center(ui.icon_card_item);
                lv_obj_add_style(ui.icon_card_item, icon_card_styles[j], 0);
​
                ui.item_img_label = lv_label_create(ui.icon_card_item);
                lv_obj_set_style_text_font(ui.item_img_label, &lv_icon_first_line_fonticon_32, 0);
                lv_label_set_text(ui.item_img_label, icon_card_item_symbols[j]);
                lv_obj_align(ui.item_img_label, LV_ALIGN_CENTER, 0, -10);
                lv_obj_add_style(ui.item_img_label, &style.icon_card_icon_color_style, 0);
​
                ui.item_img_symbol = lv_label_create(ui.icon_card_item);
                lv_label_set_text(ui.item_img_symbol, icon_card_items_name[j]);
                lv_obj_set_style_text_font(ui.item_img_symbol, &lv_font_alimama_dongfang_16, 0);
                lv_obj_align_to(ui.item_img_symbol, ui.icon_card_item, LV_ALIGN_BOTTOM_MID, 0, 0);
                lv_obj_add_style(ui.item_img_symbol, &style.icon_card_txt_color_style, 0);
            }
        }
    }
    for (i = 0; i < 3; i++)
    {
        // 第四行(3张卡片)
        ui.icon_card_item = lv_btn_create(ui.icon_card_items);
        lv_obj_set_size(ui.icon_card_item, 299, 268);
        lv_obj_center(ui.icon_card_item);
        lv_obj_add_style(ui.icon_card_item, icon_card_styles[i], 0);
​
        ui.item_img_label = lv_label_create(ui.icon_card_item);
        lv_obj_set_style_text_font(ui.item_img_label, &lv_icon_first_line_fonticon_32, 0);
        lv_label_set_text(ui.item_img_label, icon_card_item_symbols[i]);
        lv_obj_align(ui.item_img_label, LV_ALIGN_CENTER, 0, -10);
        lv_obj_add_style(ui.item_img_label, &style.icon_card_icon_color_style, 0);
​
        ui.item_img_symbol = lv_label_create(ui.icon_card_item);
        lv_label_set_text(ui.item_img_symbol, icon_card_items_name[i]);
        lv_obj_set_style_text_font(ui.item_img_symbol, &lv_font_alimama_dongfang_16, 0);
        lv_obj_align_to(ui.item_img_symbol, ui.icon_card_item, LV_ALIGN_BOTTOM_MID, 0, 0);
        lv_obj_add_style(ui.item_img_symbol, &style.icon_card_txt_color_style, 0);
    }
}

5.8.2 头文件

当然,还有对应的头文件:lv_font_icon_app.h

/**
 * @file lv_font_icon_app.h
 *
 */
​
#include "../lvgl.h"
​
#ifndef LV_FONT_ICON_APP_H
#define LV_FONT_ICON_APP_H
​
// 屏幕分辨率
#define APP_HOR_RES 1200
#define APP_VER_RES 600
​
// Flex布局的分辨率(暂时没有使用,适配太麻烦啦~)
#define FLEX_BANNER_W 1160
#define FLEX_BANNER_H 230
#define FLEX_LAYOUT_ITEM_W 360
#define FLEX_LAYOUT_ITEM_H 291
#define FLEX_LAYOUT_ITEM_IMG_W 330
#define FLEX_LAYOUT_ITEM_IMG_H 178
​
// APP颜色宏
#define APP_BG_COLOR                lv_color_hex(0xfafafb)
#define HEADER_BG_COLOR             lv_color_hex(0x1E1E1E)
​
// 单独配色宏
#define WHITE_COLOR                 lv_color_hex(0xffffff)
#define BLACK_COLOR                 lv_color_hex(0x000000)
​
// 字体卡片页面颜色宏
#define FONT_CARD_BG_COLOR          lv_color_hex(0xfafafb)
#define BANNER_FONT_COLOR           lv_color_hex(0xe8e8e8)
​
// 图标卡片页面颜色宏
#define ICON_CARD_ITEM_COLOR1       lv_color_hex(0x7ac1fa)
#define ICON_CARD_ITEM_COLOR2       lv_color_hex(0xe39af5)
#define ICON_CARD_ITEM_COLOR3       lv_color_hex(0xfb8588)
#define ICON_CARD_ITEM_COLOR4       lv_color_hex(0x6de6bf)
#define ICON_CARD_ITEM_COLOR5       lv_color_hex(0xb199fa)
#define ICON_CARD_ITEM_COLOR6       lv_color_hex(0xffffff)
#define ICON_CARD_TXT_COLOR         lv_color_hex(0x183153)
#define ICON_CARD_BANNER_COLOR      lv_color_hex(0xf0f6fc)
​
// 图像声明
LV_IMG_DECLARE(lv_font_banner_img);         // 阿里妈妈banner图片
LV_IMG_DECLARE(lv_icon_banner_img);         // FontAwesome banner图片
LV_IMG_DECLARE(lv_img_fangyuan);            // 方圆体图片
LV_IMG_DECLARE(lv_img_daoli);               // 刀隶体图像
LV_IMG_DECLARE(lv_img_lingdong);            // 灵动体图像
LV_IMG_DECLARE(lv_img_dongfang);            // 东方大楷图像
LV_IMG_DECLARE(lv_img_shuhei);              // 数黑体图像
LV_IMG_DECLARE(lv_img_ruantang);            // 软糖初恋体图像
​
// 导入字体声明
LV_FONT_DECLARE(lv_icon_gallery_bar_font_14);  // 状态栏字体(东方大楷14号字)
LV_FONT_DECLARE(lv_icon_banner_font_16);       // 图标版面图(软糖初恋体16号字)
LV_FONT_DECLARE(lv_font_banner_ruantang_16);   // 字体版面图(软糖初恋体16号字)
LV_FONT_DECLARE(lv_icon_banner_title_font_18); // 图标版面图标题(东方大楷18号字)
LV_FONT_DECLARE(lv_font_alimama_fangyuan_16);  // 阿里妈妈·方圆体
LV_FONT_DECLARE(lv_font_alimama_daoli_16);     // 阿里妈妈·刀隶体
LV_FONT_DECLARE(lv_font_alimama_lingdong_16);  // 阿里妈妈·灵动体
LV_FONT_DECLARE(lv_font_alimama_dongfang_16);  // 阿里妈妈·东方大楷
LV_FONT_DECLARE(lv_font_alimama_shuhei_16);    // 阿里妈妈·数黑体
LV_FONT_DECLARE(lv_font_ruantang_16);          // 软糖初恋体
​
// Symbol/字体声明
LV_FONT_DECLARE(lv_icon_gallery_bar_icons_16); // 导航栏图标字体
#define LV_SYMBOL_SIGNAL_ICON       "\xEE\x98\x80"          // 手机信号
#define LV_SYMBOL_ZHONGQIU_ICON     "\xEE\x98\xA7"          // 中秋月亮🌕
#define LV_SYMBOL_YUELIANG_ICON     "\xEE\x9A\x88"          // 月牙月亮
#define LV_SYMBOL_TOPIC             "\xEE\xA2\xB1"          // 话题
​
LV_FONT_DECLARE(lv_icon_gallery_banner_logo_30);            // 版面图图标字体
#define LV_SYMBOL_ZHONGQIU_ICON     "\xEE\x98\xA7"          // 中秋月亮🌕
#define LV_SYMBOL_YUELIANG_ICON     "\xEE\x9A\x88"          // 月牙月亮
#define LV_SYMBOL_TOPIC             "\xEE\xA2\xB1"          // 话题
​
LV_FONT_DECLARE(lv_icon_first_line_fonticon_32); // 第一行图标字体
#define LV_SYMBOL_EMOJI             "\xEE\x98\x87"          // 笑脸🤣
#define LV_SYMBOL_FRUIT             "\xEE\x9B\x8D"          // 草莓🍓
#define LV_SYMBOL_ALPHABET          "\xEE\x98\x81"          // 字母A
#define LV_SYMBOL_MARITIME          "\xEE\x98\x94"          // 海洋的🦀
#define LV_SYMBOL_SCIENCE           "\xEE\xA6\x98"          // 科学✈️
#define LV_SYMBOL_SORT              "\xEE\x9B\xA5"          // 分类
​
typedef struct
{
​
    lv_obj_t *screen_app;           // 主页面
​
    lv_obj_t *header_container;     // 头部区域
​
    lv_obj_t *status_bar;           // 状态栏
    lv_obj_t *status_signal_icon;   // 信号图标
    lv_obj_t *status_signal_text;   // 信号图标文本
    lv_obj_t *status_time_icon;     // 时间图标
    lv_obj_t *status_battery_icon;  // 电池图标
    lv_obj_t *status_wifi_icon;     // WIFI图标
    lv_obj_t *status_gps_icon;      // GPS图标
​
    lv_obj_t *content_switcher;     // 页面选择按钮
    lv_obj_t *font_gallery_btn;     // 字体页面切换按钮
    lv_obj_t *icon_gallery_btn;     // 图标页面切换按钮
​
    lv_obj_t *font_card_area;       // 字体展示页面
    lv_obj_t *font_card_container;  // 字体页面内嵌子项
​
    lv_obj_t *font_banner;          // 字体页版面图
    lv_obj_t *font_banner_img;      // 版面图Image(图片)
    lv_obj_t *banner_content;       // 版面图文本
​
    lv_obj_t *font_card_items;      // 图标卡片项
    lv_obj_t *font_card_item;       // 卡片子项
    lv_obj_t *font_card_img;        // 卡片图像
    lv_obj_t *font_card_txt;        // 卡片文本
​
    lv_obj_t *fangyuan_font_card;   // 方圆体卡片
    lv_obj_t *fangyuan_card_img;    // 方圆体卡片图片
    lv_obj_t *fangyuan_card_txt;    // 方圆体文本
​
    lv_obj_t *daoli_font_card;      // 刀隶体卡片
    lv_obj_t *daoli_card_img;       // 刀隶体卡片图片
    lv_obj_t *daoli_card_txt;       // 刀隶体文本
​
    lv_obj_t *lingdong_font_card;   // 灵动体卡片
    lv_obj_t *lingdong_card_img;    // 灵动体卡片图片
    lv_obj_t *lingdong_card_txt;    // 灵动体文本
​
    lv_obj_t *dongfang_font_card;   // 东方大楷卡片
    lv_obj_t *dongfang_card_img;    // 东方大楷卡片图片
    lv_obj_t *dongfang_card_txt;    // 东方大楷文本
​
    lv_obj_t *shuhei_font_card;     // 数黑体卡片
    lv_obj_t *shuhei_card_img;      // 数黑体卡片图片
    lv_obj_t *shuhei_card_txt;      // 数黑体文本
​
    lv_obj_t *ruantang_font_card;   // 软糖初恋体卡片
    lv_obj_t *ruantang_card_img;    // 软糖初恋体卡片图片
    lv_obj_t *ruantang_card_txt;    // 软糖初恋体文本
​
    lv_obj_t *icon_card_area;       // 图标展示页面
    lv_obj_t *icon_card_container;  // 图标页面内嵌子项
​
    lv_obj_t *icon_banner;          // 图标页版面图
    lv_obj_t *icon_banner_img;      // 版面图图片
    lv_obj_t *icon_banner_logo;     // 版面图logo
    lv_obj_t *icon_banner_title;    // 版面图标题
    lv_obj_t *icon_banner_txt;      // 版面图介绍
​
    lv_obj_t *icon_card_items;      // 图标卡片项
    lv_obj_t *icon_card_item;       // 卡片子项
    lv_obj_t *item_img_label;       // 卡片子项符号图像
    lv_obj_t *item_img_symbol;      // 卡片Symbol图像
​
} ui_objs_t;
ui_objs_t ui; // 初始化结构体的实例(ui)
​
typedef struct
{
    lv_style_t app_scr_style;
​
    lv_style_t app_header_style;
    lv_style_t status_bar_style;
    lv_style_t status_icon_style;
    lv_style_t content_switcher_style;
​
    lv_style_t page_sw_btn_txt_style;
    lv_style_t banner_style;
​
    lv_style_t font_card_items_style;
    lv_style_t font_card_item_style;
​
    lv_style_t icon_card_items_style;
    lv_style_t icon_card_item_style;
​
    lv_style_t icon_card_item1_style;
    lv_style_t icon_card_item2_style;
    lv_style_t icon_card_item3_style;
    lv_style_t icon_card_item4_style;
    lv_style_t icon_card_item5_style;
    lv_style_t icon_card_item6_style;
​
    lv_style_t icon_card_txt_color_style;
    lv_style_t icon_card_icon_color_style;
} ui_styles_t;
​
static ui_styles_t style; // 初始化结构体实例(style)
​
// 用于控制循环函数迭代次数
int16_t i;
int16_t j;
​
void lv_font_icon_app(void);
​
#endif  // LV_FONT_ICON_APP_H

5.9 页面切换

为什么最后才写这个呢?因为我也不知道放在哪合适,或许大多数人复制完代码就跑路了,点赞、收藏、关注也没有,作者喝西北风的时候,记得别帮作者关窗户奥~

在本次Demo中,使用的还是比较不那么正规的页面管理

1. 该项目的UI页面,包括一个主页面,和2个待切换显示页面区域。
2. 初始化的时候,设置第二个区域(ui.icon_card_area) 为隐藏
3. 通过2个切换按钮,添加回调函数(去检测按钮的点击事件响应的时候 -> 执行页面的隐藏与显示)

那么~请👀看这里。下面👇就是对应的切换代码啦。

1. code 是诸如:点击按钮、鼠标放在按钮上、鼠标长时间点击按钮等事件
2. target 是点击或操作的obj(对象)的名称
3. 通过获取按钮的文本名称,当发现是点击事件的时候,对应不同按钮执行点击事件。切换到对应的页面
4. 上面👆的切换原理:添加或移除隐藏页面的效果

恭喜🎉你看到了这里,快去动手试试吧~

喜欢我的demo的话,可以一键三连奥~这里是 还有一天就退休了

参考文献:

1 - UI设计灵感1:iconfont-阿里巴巴矢量图标库

2 - UI设计灵感2:Font Awesome

2 - 字体文件编码范围查询:https://voq.me/character-map/

3 - LVGL转换工具:Font Converter — LVGL

4 - .otf字体格式转换:OTF 转换器 - 免费在线转换您的OTF文件

5 - Unicde -> Hex code(utf-8):UTF-8 Tool

6 - LVGL8.x样式:LVGL V8样式_lv obj set style border side-CSDN博客

7 - windows颜色提取工具:使用 Color Picker 颜色选择器,瞬间拾取想要的颜色代码

8 - 颜色选择:HTML Color Codes

9 - 图片显示:LVGL移植和图片显示_lvgl 显示图片-CSDN博客

10 - LVGL-8.3安装教程:关于用windows搭建lvgl_port_pc_vscode(V9)时碰到的一些问题_windows lvgl-CSDN博客

11- GIF在线压缩:免费在线 GIF 动图压缩工具 - docsmall

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值