• 【LVGL】弹性布局(Flex)学习


    Flex(弹性布局)

    概述:

    1. 弹性布局(Flex)可以调整父级中所有的子元素所排列的位置,例如:成行排列、成列排列;
    2. 可以调整不同高度和不同宽度的子元素如何排列和放置
    3. 排列时是否可以换行

    所在目录:src\extra\layouts\flex

    /**
     * Set hot the item should flow
     * @param flex pointer to a flex layout descriptor
     * @param flow an element of `lv_flex_flow_t`.
     */
    void lv_obj_set_flex_flow(lv_obj_t * obj, lv_flex_flow_t flow);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    请注意,LVGL 的 flex 布局功能需要通过 lv_conf.h 中的 LV_USE_FLEX 全局启用。

    形参说明:

    1. obj :指向需要弹性布局的控件指针或者容器指针
    2. flow :
     LV_FLEX_FLOW_ROW 				  //将子元素排成一排而不包裹
     LV_FLEX_FLOW_COLUMN 			  //将子项放在一列中而不换行
     LV_FLEX_FLOW_ROW_WRAP 			  //将孩子排成一排并包裹起来 (超出部分换行)
     LV_FLEX_FLOW_COLUMN_WRAP 		  //将子元素放置在带有环绕的列中 (超出部分换列)
     LV_FLEX_FLOW_ROW_REVERSE 		  //将子元素排成一行而不换行,但顺序相反
     LV_FLEX_FLOW_COLUMN_REVERSE 	  //将子项放在一列中,不换行,但顺序相反
     LV_FLEX_FLOW_ROW_WRAP_REVERSE 	  //将子元素排成一行而不换行,但顺序相反
     LV_FLEX_FLOW_COLUMN_WRAP_REVERSE //将子项放在一列中,不换行,但顺序相反
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    举例1: LV_FLEX_FLOW_ROW

        lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW);        // 设置对象容器使用基于行的流失弹性布局flex
    
    • 1

    在这里插入图片描述
    举例2: LV_FLEX_FLOW_COLUMN

        lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);        // 设置对象容器使用基于行的流失弹性布局flex
    
    • 1

    在这里插入图片描述
    举例3: LV_FLEX_FLOW_ROW_WRAP

        lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP);        // 设置对象容器使用基于行的流失弹性布局flex
    
    • 1

    在这里插入图片描述
    举例4: LV_FLEX_FLOW_COLUMN_WRAP

        lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN_WRAP);        // 设置对象容器使用基于行的流失弹性布局flex
    
    • 1

    在这里插入图片描述
    举例5: LV_FLEX_FLOW_ROW_REVERSE

        lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_REVERSE);        // 设置对象容器使用基于行的流失弹性布局flex
    
    • 1

    在这里插入图片描述
    以下三种只是顺序反了,不在举例
    LV_FLEX_FLOW_COLUMN_REVERSE
    LV_FLEX_FLOW_ROW_WRAP_REVERSE
    LV_FLEX_FLOW_COLUMN_WRAP_REVERSE

    设置如何放置(在哪里对齐)项目和轨道

    /**
     * Set how to place (where to align) the items and tracks
     * @param flex pointer: to a flex layout descriptor
     * @param main_place where to place the items on main axis (in their track). Any value of `lv_flex_align_t`.
     * @param cross_place where to place the item in their track on the cross axis. `LV_FLEX_ALIGN_START/END/CENTER`
     * @param track_place where to place the tracks in the cross direction. Any value of `lv_flex_align_t`.
     */
    void lv_obj_set_flex_align(lv_obj_t * obj, lv_flex_align_t main_place, lv_flex_align_t cross_place,
                               lv_flex_align_t track_cross_place);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    函数说明:

    设置子元素集在父级中的轨道分布和对齐方式

    形参说明:

    1. 父级对象指针
    2. 负责改变每行元素的间距( 确定如何在主轴上的轨道中分布项目)
    3. 改变每行元素上下对齐的方式(确定如何在横轴上的轨道中分布项目)
    4. 设置内容区域的位置(确定如何分配轨道,注意:LV_FLEX_ALIGN_SPACE_EVENLY LV_FLEX_ALIGN_SPACE_AROUND LV_FLEX_ALIGN_SPACE_BETWEEN 无法使用)

    lv_flex_align_t

    typedef enum {
        LV_FLEX_ALIGN_START,			//表示在水平方向和垂直方向的顶部左侧。 (默认)
        LV_FLEX_ALIGN_END,				//表示水平和底部垂直
        LV_FLEX_ALIGN_CENTER,			//只是居中
        LV_FLEX_ALIGN_SPACE_EVENLY,		//项目是分布的,因此任意两个项目之间的间距(以及到边缘的空间)是相等的。 不适用于 track_cross_place
        LV_FLEX_ALIGN_SPACE_AROUND,		//项目均匀分布在轨道中,它们周围的空间相等。 请注意,视觉上的空间并不相等,因为所有项目的两侧都有相等的空间。 第一个项目将与容器边缘有一个单位的空间,但下一个项目之间有两个单位的空间,因为下一个项目有自己的适用间距。 不适用于track_cross_place
        LV_FLEX_ALIGN_SPACE_BETWEEN,	// 项目均匀分布在轨道中:第一个项目在开始线上,最后一个项目在结束线上。 不适用于track_cross_place。
    } lv_flex_align_t;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    举例1:

    所有btn子元素都距离容器25个像素,各个btn子元素间距均匀分部,和底部对齐

        lv_obj_t* cont = lv_obj_create(lv_scr_act());               // 创建一个对象容器 cont
        lv_obj_set_size(cont, 400, 200);                            // 设置对象容器大小
        lv_obj_align(cont, LV_ALIGN_TOP_MID, 0, 5);                 // 设置对象容器基于屏幕中间对齐
        lv_obj_set_style_pad_all(cont, 25, LV_PART_MAIN);           // 设置对象容器内部 item 与容器边的上下左右间距
        //lv_obj_set_style_pad_row(cont, 10, LV_PART_MAIN);           // 设置对象容器内部 item 之间的行间距
        //lv_obj_set_style_pad_column(cont, 10, LV_PART_MAIN);        // 设置对象容器内部 item 之间的列间距
        lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);            // 取消滚动条
    
        lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP);          // 设置对象容器使用基于行的流失弹性布局flex,设置超出部分换行模式
    
        /**
         * 设置容器弹性模式
         * 1. 容器指针
         * 2. LV_FLEX_ALIGN_SPACE_EVENLY 均匀分部子元素之间的间距
         * 3. LV_FLEX_ALIGN_END 容器中所有的子元素底部对齐
         * 4. 默认0
        */
        lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_END, 0);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    举例2:
    各个btn子元素间距均匀分部,和每行子元素底部对齐,两边距离容器边框25个像素,子元素的区域位置向容器中心对齐,并均匀分部。

        lv_obj_t* cont = lv_obj_create(lv_scr_act());               // 创建一个对象容器 cont
        lv_obj_set_size(cont, 350, 420);                            // 设置对象容器大小
        lv_obj_align(cont, LV_ALIGN_TOP_MID, 0, 5);                 // 设置对象容器基于屏幕中间对齐
        lv_obj_set_style_pad_all(cont, 25, LV_PART_MAIN);           // 设置对象容器内部 item 与容器边的上下左右间距
        //lv_obj_set_style_pad_row(cont, 10, LV_PART_MAIN);           // 设置对象容器内部 item 之间的行间距
        //lv_obj_set_style_pad_column(cont, 10, LV_PART_MAIN);        // 设置对象容器内部 item 之间的列间距
        lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);            // 取消滚动条
    
        lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP);          // 设置对象容器使用基于行的流失弹性布局flex,设置超出部分换行模式
    
        /**
         * 设置容器弹性模式
         * 1. 容器指针
         * 2. LV_FLEX_ALIGN_SPACE_EVENLY 均匀分部子元素之间的间距
         * 3. LV_FLEX_ALIGN_END          容器中每行所有的子元素底部对齐
         * 4. LV_FLEX_ALIGN_CENTER       容器中内容的子元素向容器中心对齐
        */
        lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_CENTER);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    举例3:
    各个btn子元素间距均匀分部,和每行子元素底部对齐,子元素的区域位置向容器顶部对齐并距离顶边和两边25个像素,并均匀分部。

        lv_obj_t* cont = lv_obj_create(lv_scr_act());               // 创建一个对象容器 cont
        lv_obj_set_size(cont, 350, 420);                            // 设置对象容器大小
        lv_obj_align(cont, LV_ALIGN_TOP_MID, 0, 5);                 // 设置对象容器基于屏幕中间对齐
        lv_obj_set_style_pad_all(cont, 25, LV_PART_MAIN);           // 设置对象容器内部 item 与容器边的上下左右间距
        //lv_obj_set_style_pad_row(cont, 10, LV_PART_MAIN);           // 设置对象容器内部 item 之间的行间距
        //lv_obj_set_style_pad_column(cont, 10, LV_PART_MAIN);        // 设置对象容器内部 item 之间的列间距
        lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);            // 取消滚动条
    
        lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP);          // 设置对象容器使用基于行的流失弹性布局flex,设置超出部分换行模式
    
        /**
         * 设置容器弹性模式
         * 1. 容器指针
         * 2. LV_FLEX_ALIGN_SPACE_EVENLY 均匀分部子元素之间的间距
         * 3. LV_FLEX_ALIGN_END          容器中所有的子元素底部对齐
         * 4. LV_FLEX_ALIGN_CENTER       容器中内容的子元素向容器顶部对齐
        */
        lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_START);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    以下来自其它参考图片图片

    lv_obj_set_flex_align 参数4,参考图片
    在这里插入图片描述
    lv_obj_set_flex_align 参数2和参数3,参考图片
    在这里插入图片描述
    Flex CSS

    下笔如有神

    测试案例:

    static lv_style_t style_label;
    static lv_obj_t* cont;
    static lv_obj_t* cont_main;
    
    
    LV_FONT_DECLARE(myFontOrbitron_18);
    
    
    
    void test_demo(void)
    {
    
        lv_obj_t* cont = lv_obj_create(lv_scr_act());               // 创建一个对象容器 cont
        lv_obj_set_size(cont, 350, 420);                            // 设置对象容器大小
        lv_obj_align(cont, LV_ALIGN_TOP_MID, 0, 5);                 // 设置对象容器基于屏幕中间对齐
        lv_obj_set_style_pad_all(cont, 25, LV_PART_MAIN);           // 设置对象容器内部 item 与容器边的上下左右间距
        //lv_obj_set_style_pad_row(cont, 10, LV_PART_MAIN);           // 设置对象容器内部 item 之间的行间距
        //lv_obj_set_style_pad_column(cont, 10, LV_PART_MAIN);        // 设置对象容器内部 item 之间的列间距
        lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);            // 取消滚动条
    
        lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP);          // 设置对象容器使用基于行的流失弹性布局flex,设置超出部分换行模式
    
        /**
         * 设置容器弹性模式
         * 1. 容器指针
         * 2. LV_FLEX_ALIGN_SPACE_EVENLY 均匀分部子元素之间的间距
         * 3. LV_FLEX_ALIGN_END          容器中所有的子元素底部对齐
         * 4. LV_FLEX_ALIGN_CENTER       容器中内容的子元素向容器中心对齐
        */
        lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_START);
    
    
    
    
        static lv_style_t btn_style;
        lv_style_init(&btn_style);                           // 初始化样式
        lv_style_set_radius(&btn_style, 5);                  // 设置样式圆角为0
    
        lv_obj_t* btn1 = lv_btn_create(cont);                // 基于cont对象添加button对象
        lv_obj_set_size(btn1, 100, 80);                       // 设置对象大小
    
        lv_obj_t* btn1_label = lv_label_create(btn1);        // 创建按键对象创建label对象
        lv_label_set_text(btn1_label, "Btn1");               // 设置label文本
        lv_obj_center(btn1_label);                           // label对象居中显示
        lv_obj_add_style(btn1, &btn_style, LV_PART_MAIN);    // 配置样式
    
        lv_obj_t* btn2 = lv_btn_create(cont);                // 基于cont对象添加button对象
        lv_obj_set_size(btn2, 80, 110);                      // 设置对象大小
    
        lv_obj_t* btn2_label = lv_label_create(btn2);        // 创建按键对象创建label对象
        lv_label_set_text(btn2_label, "Btn2");               // 设置label文本
        lv_obj_center(btn2_label);                           // label对象居中显示
        lv_obj_add_style(btn2, &btn_style, LV_PART_MAIN);    // 配置样式
    
        lv_obj_t* btn3 = lv_btn_create(cont);                // 基于cont对象添加button对象
        lv_obj_set_size(btn3, 45, 30);                       // 设置对象大小
    
        lv_obj_t* btn3_label = lv_label_create(btn3);        // 创建按键对象创建label对象
        lv_label_set_text(btn3_label, "Btn3");               // 设置label文本
        lv_obj_center(btn3_label);                           // label对象居中显示
        lv_obj_add_style(btn3, &btn_style, LV_PART_MAIN);    // 配置样式
    
        lv_obj_t* btn4 = lv_btn_create(cont);                // 基于cont对象添加button对象
        lv_obj_set_size(btn4, 60, 35);                       // 设置对象大小
    
        lv_obj_t* btn4_label = lv_label_create(btn4);        // 创建按键对象创建label对象
        lv_label_set_text(btn4_label, "Btn4");               // 设置label文本
        lv_obj_center(btn4_label);                           // label对象居中显示
        lv_obj_add_style(btn4, &btn_style, LV_PART_MAIN);    // 配置样式
    
        lv_obj_t* btn5 = lv_btn_create(cont);                // 基于cont对象添加button对象
        lv_obj_set_size(btn5, 70, 50);                       // 设置对象大小
    
        lv_obj_t* btn5_label = lv_label_create(btn5);        // 创建按键对象创建label对象
        lv_label_set_text(btn5_label, "Btn5");               // 设置label文本
        lv_obj_center(btn5_label);                           // label对象居中显示
        lv_obj_add_style(btn5, &btn_style, LV_PART_MAIN | LV_STATE_PRESSED);    // 配置样式
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
  • 相关阅读:
    .NET Core MongoDB数据仓储和工作单元模式封装
    创建线程池
    代码随想录Day52 | 300. 最长递增子序列 | 674. 最长连续递增序列 | 718. 最长重复子数组
    什么是AES加密?详解AES加密算法原理流程
    【Vue基础七】--- 组件和模块概念
    windows10下安装fbprophet及使用虚拟环境
    PHP 利用getid3 获取mp3、mp4、wav等媒体文件时长等数据
    深度学习中几种常见数据标准化方法
    C++——list
    MQ系列4:NameServer 原理解析
  • 原文地址:https://blog.csdn.net/shileiwu0505/article/details/126925132