wordpress必须先登录,seo泛目录培训,苏州现代建设公司网站,成都住房和城乡建设官网文章目录 前言一、Style的介绍二、State状态三、级联样式四、Style的继承五、组件六、设置样式属性七、添加和移除样式7.1 添加7.2 替换样式7.3 移除样式7.4 当对象实时改变了样式去通知对象刷新样式 八、获取一个对象的属性值九、本地样式十、过度动画十一、主题总结 前言
在… 文章目录 前言一、Style的介绍二、State状态三、级联样式四、Style的继承五、组件六、设置样式属性七、添加和移除样式7.1 添加7.2 替换样式7.3 移除样式7.4 当对象实时改变了样式去通知对象刷新样式 八、获取一个对象的属性值九、本地样式十、过度动画十一、主题总结 前言
在LVGL 9的图形用户界面GUI开发中Style样式是一项至关重要的功能为界面元素的外观和行为提供了强大的定制能力。Style可以定义元素的颜色、边框、字体等各种视觉和行为属性使得开发者能够轻松实现各种独特而漂亮的界面设计。本文将深入探讨LVGL 9中Style样式的使用方法帮助开发者更好地掌握这一关键技术创造出令人印象深刻的用户界面。 一、Style的介绍
样式是一个 lv_style_t 类型的变量可以包含诸如边框宽度、文本颜色等属性。这类似于CSS中的类class的概念。 样式可以被分配给对象以改变它们的外观。在分配时可以指定目标部分CSS中的伪元素和目标状态伪类。例如可以在滑块的旋钮处添加 style_blue以在按下状态下改变其外观。 同一样式可以被任意数量的对象共享使用。 样式可以被层叠这意味着可以分配多个样式给一个对象每个样式可以有不同的属性。因此并非所有属性都必须在一个样式中指定。LVGL将在样式中搜索属性直到找到定义该属性的样式或者如果没有样式定义则使用默认值。例如style_btn 可以产生默认的灰色按钮而 style_btn_red 可以仅添加一个 background-colorred 以覆盖背景颜色。 最近添加的样式具有更高的优先级。这意味着如果一个属性在两个样式中都有指定对象中最新添加的样式将被使用。 一些属性例如文本颜色可以从父级继承如果在对象中没有指定。 对象还可以具有比“普通”样式更高优先级的本地样式。 与CSS不同在其中伪类描述不同的状态例如 :focus在LVGL中属性被分配给给定的状态。 可以在对象状态改变时应用过渡效果。
二、State状态
我们的lvgl的样式是在不同状态下有不同的样式的 这些对象可以处于以下状态的组合
LV_STATE_DEFAULT0x0000正常释放状态
LV_STATE_CHECKED0x0001切换或选中状态
LV_STATE_FOCUSED0x0002通过键盘、旋钮聚焦或通过触摸板/鼠标点击聚焦
LV_STATE_FOCUS_KEY0x0004通过键盘或旋钮聚焦但不通过触摸板/鼠标
LV_STATE_EDITED0x0008由旋钮编辑
LV_STATE_HOVERED0x0010被鼠标悬停目前不支持
LV_STATE_PRESSED0x0020正在被按下
LV_STATE_SCROLLED0x0040正在被滚动
LV_STATE_DISABLED0x0080禁用状态
LV_STATE_USER_10x1000自定义状态
LV_STATE_USER_20x2000自定义状态
LV_STATE_USER_30x4000自定义状态
LV_STATE_USER_40x8000自定义状态一个对象可以同时处于多种状态的组合比如同时处于焦点和被按下的状态表示为 LV_STATE_FOCUSED | LV_STATE_PRESSED。
可以向任何状态或状态组合添加样式。例如为默认和按下的状态设置不同的背景颜色。如果一个属性在某个状态中没有定义将使用最匹配状态的属性。通常这意味着将使用具有 LV_STATE_DEFAULT 的属性。如果甚至对于默认状态也没有设置属性将使用默认值见后文。
但是“最匹配状态的属性”到底是什么意思呢状态的优先级由它们的值表示见上面的列表。值越高优先级越高。为了确定要使用哪个状态的属性让我们来看一个例子。想象一下背景颜色定义如下
LV_STATE_DEFAULT白色
LV_STATE_PRESSED灰色
LV_STATE_FOCUSED红色最初对象处于默认状态因此这是一个简单的情况属性在对象当前状态中完美定义为白色。
当对象被按下时有两个相关的属性默认为白色默认与每个状态相关按下为灰色。按下的状态具有0x0020的优先级这比默认状态的0x0000优先级更高因此将使用灰色。
当对象被聚焦时与按下状态相同的情况发生红色将被使用。聚焦状态优先级高于默认状态
当对象既聚焦又被按下时灰色和红色都可以工作但按下状态的优先级高于聚焦状态因此将使用灰色。
可以设置例如玫瑰色为 LV_STATE_PRESSED | LV_STATE_FOCUSED。在这种情况下此组合状态的优先级为0x0020 0x0002 0x0022高于按下状态的优先级因此将使用玫瑰色。
当对象处于已选状态时没有设置此状态的背景颜色的属性。因此由于没有更好的选择对象将保持来自默认状态属性的白色。
一些建议 状态的优先级值相当直观用户会自然而然地期望的。例如如果对象聚焦用户仍然希望看到它是否被按下因此按下状态具有更高的优先级。如果聚焦状态具有更高的优先级它将覆盖按下的颜色。 如果要为所有状态设置属性例如红色背景颜色只需为默认状态设置即可。如果对象找不到其当前状态的属性它将回退到默认状态的属性。 使用按位或运算的状态描述复杂的情况。例如按下 已选 聚焦 对于不同的状态使用不同的样式元素可能是一个不错的主意。例如为释放、按下、已选 按下、聚焦等状态找到不同的背景颜色。
三、级联样式
在样式层叠中不需要在一个样式中设置所有属性。可以向对象添加更多样式使后添加的样式修改或扩展外观。例如创建一个通用的灰色按钮样式然后创建一个新的红色按钮样式只设置新的背景颜色。
这与CSS中使用类列表的方式很相似例如 div class“.btn .btn-red”。
后添加的样式优先于先前设置的样式。因此在上述灰色/红色按钮示例中应该先添加普通按钮样式然后再添加红色样式。然而仍然要考虑状态的优先级。因此让我们来看下面的情况
基本按钮样式为默认状态定义深灰色为按下状态定义浅灰色。
红色按钮样式仅在默认状态下将背景颜色定义为红色。
在这种情况下当按钮释放时处于默认状态它将是红色因为在最近添加的样式红色中找到了完全匹配。当按钮被按下时浅灰色是更好的匹配因为它完美地描述了当前状态所以按钮将是浅灰色。
四、Style的继承
有些属性通常是与文本相关的属性可以从父对象的样式中继承。仅当对象的样式中未设置给定属性时即使在默认状态下也未设置才会应用继承。在这种情况下如果属性是可继承的将在父级中查找该属性的值直到某个对象为该属性指定一个值为止。父级将使用自己的状态来确定该值。因此如果按钮被按下文本颜色是从这里继承的那么将使用按下状态的文本颜色。
五、组件
对象可以由各个部分组成每个部分都可以拥有自己的样式。
在LVGL中存在以下预定义的部分
LV_PART_MAIN: 像矩形一样的背景
LV_PART_SCROLLBAR: 滚动条
LV_PART_INDICATOR: 指示器例如用于滑块、进度条、开关或复选框的勾选框
LV_PART_KNOB: 类似于手柄用于调整数值
LV_PART_SELECTED: 指示当前选定的选项或部分
LV_PART_ITEMS: 如果小部件具有多个相似的元素例如表格单元则使用此部分
LV_PART_CURSOR: 标记特定的位置例如文本区域或图表的光标
LV_PART_CUSTOM_FIRST: 从这里开始可以添加自定义部分标识符。上面这些可以搭配我们的State表示某一个状态下我的某个地方是什么样式
六、设置样式属性
样式被存储在lv_style_t类型的变量中。样式变量应该是静态的、全局的或者是动态分配的。换句话说它们不能是在函数退出时销毁的局部变量。在使用样式之前应该使用lv_style_init(my_style)来初始化样式。初始化样式后可以添加或更改属性。 使用lv_style_set_property_name(style, value);来设置样式
示例代码
static lv_style_t style_btn;
lv_style_init(style_btn);
lv_style_set_bg_color(style_btn, lv_color_hex(0x115588));//背景颜色
lv_style_set_bg_opa(style_btn, LV_OPA_50);//背景的透明度
lv_style_set_border_width(style_btn, 2);//边框的宽度
lv_style_set_border_color(style_btn, lv_color_black());//边框的颜色static lv_style_t style_btn_red;
lv_style_init(style_btn_red);
lv_style_set_bg_color(style_btn_red, lv_plaette_main(LV_PALETTE_RED));
lv_style_set_bg_opa(style_btn_red, LV_OPA_COVER);移除样式的某个属性lv_style_remove_prop(style, LV_STYLE_property_name); 例如lv_style_remove_prop(style, LV_STYLE_BG_COLOR);移除背景颜色
获取样式某个属性的值lv_style_get_prop(style, LV_STYLE_property_name, v); v的类型为lv_style_value_t 返回值为是否获取成功
示例代码
lv_style_value_t v;
lv_res_t res lv_style_get_prop(style, LV_STYLE_BG_COLOR, v);
if(res LV_RES_OK) { /*Found*/do_something(v.color);
}我们可以通过lv_res_t里面的成员获取值
七、添加和移除样式
7.1 添加
我们可以使用这个函数lv_obj_add_style(obj, style, selector)selector 是由部分和状态进行逻辑 OR 操作得到的值用于指定应该添加样式的对象。
例如
LV_PART_MAIN | LV_STATE_DEFAULT
LV_STATE_PRESSED: 处于按下状态的主要部分。LV_PART_MAIN 可以省略。
LV_PART_SCROLLBAR: 默认状态下的滚动条部分。LV_STATE_DEFAULT 可以省略。
LV_PART_SCROLLBAR | LV_STATE_SCROLLED: 当对象正在滚动时的滚动条部分。
LV_PART_INDICATOR | LV_STATE_PRESSED | LV_STATE_CHECKED: 对象被按下且同时处于选中状态时的指示器部分。使用这个函数添加样式示例代码
lv_obj_add_style(btn, style_btn, 0); /*默认*/
lv_obj_add_style(btn, btn_red, LV_STATE_PRESSED); /*改变点击时的颜色*/7.2 替换样式
我们可以使用这个函数lv_obj_replace_style(obj, old_style, new_style, selector) 注意这个函数只有在选择器与lv_obj_add_style中使用的选择器匹配时才会用new_style替换old_style。两种样式即old_style和new_style都不能为NULL有专门的添加和移除函数来处理。如果在对象的样式中多次存在old_style和选择器的组合所有的出现都将被替换。函数的返回值指示是否至少发生了一次成功的替换。
示例代码
lv_obj_add_style(btn, style_btn, 0); /*Add a button style*/
lv_obj_replace_style(btn, style_btn, new_style_btn, 0); /*Replace the button style with a different one*/7.3 移除样式
lv_obj_remove_style_all(obj)
lv_obj_remove_style(obj, style, selector)我们可以使用上面这两个函数来移除样式 第一个移除所有第二个根据参数2和参数3进行移除
这个函数只有在选择器与lv_obj_add_style()中使用的选择器匹配时才会移除样式。style参数可以是NULL以仅检查选择器并移除所有匹配的样式。选择器可以使用LV_STATE_ANY和LV_PART_ANY值以从任何状态或部分移除样式。
7.4 当对象实时改变了样式去通知对象刷新样式
如果已分配给对象的样式发生更改即添加或更改了属性则使用该样式的对象应该收到通知。有三种选项可以实现这一点 如果你知道更改的属性可以通过简单的重绘来应用例如颜色或不透明度的更改只需调用lv_obj_invalidate(obj)或lv_obj_invalidate(lv_screen_active())。
如果更改或添加了更复杂的样式属性并且你知道受到该样式影响的对象是哪些调用lv_obj_refresh_style(obj, part, property)。要刷新所有部分和属性请使用lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY)。
要让 LVGL 检查所有对象看看它们是否使用了某个样式并在需要时刷新它们请调用lv_obj_report_style_change(style)。如果样式是 NULL则会通知所有对象样式已更改。
八、获取一个对象的属性值
要获取属性的最终值考虑到级联、继承、本地样式和过渡见下文可以使用如下的属性获取函数lv_obj_get_style_property_name(obj, part)。这些函数使用对象当前的状态如果没有更好的候选对象则返回默认值。例如
lv_color_t color lv_obj_get_style_bg_color(btn, LV_PART_MAIN);其中lv_color_t的定义如下
typedef struct {uint8_t blue;uint8_t green;uint8_t red;
} lv_color_t;九、本地样式
除了“普通”样式外对象还可以存储本地样式。这个概念类似于CSS中的内联样式例如 div style“color:red”但有一些修改。
本地样式与普通样式类似但不能在其他对象之间共享。如果使用本地样式会自动分配并在对象被删除时释放。它们非常适用于对对象进行本地定制。
与CSS不同LVGL的本地样式可以分配给状态伪类和部分伪元素。
要设置本地属性可以使用类似lv_obj_set_style_property_name(obj, value, selector)的函数。例如
lv_obj_set_style_bg_color(slider, lv_color_red(), LV_PART_INDICATOR | LV_STATE_FOCUSED);那么本地样式和普通样式的区别是什么 范围和共享性 普通样式Global Styles普通样式可以被多个对象共享它们可以在整个应用程序中重复使用。修改普通样式会影响到所有使用该样式的对象。 本地样式Local Styles本地样式是特定于对象的不能被其他对象共享。每个对象都可以有自己的本地样式它们只适用于拥有它们的对象。本地样式的修改只影响到拥有该样式的对象。
自动分配和释放 普通样式普通样式需要手动分配和释放。它们可以在应用程序的整个生命周期中保持不变除非显式更改或释放。 本地样式本地样式在对象创建时自动分配并在对象删除时自动释放。这意味着在对象的生命周期内不需要手动管理本地样式的分配和释放。
作用范围 普通样式普通样式通常用于全局设置可以影响多个对象的外观和行为。 本地样式本地样式通常用于对特定对象进行局部定制。它们允许对象在不影响其他对象的情况下拥有自己独特的外观和行为。
状态和部分 普通样式普通样式通常不与特定状态或部分相关联它们适用于对象的所有状态和部分。 本地样式本地样式可以与特定状态或部分相关联。这意味着可以为对象的不同状态或部分分配不同的本地样式从而实现更细粒度的外观定制。
十、过度动画
默认情况下当对象改变状态时例如被按下新状态的属性会立即设置。然而通过使用过渡效果可以在状态变化时播放动画。例如按下按钮时其背景颜色可以在300毫秒内动画变为按下时的颜色。
过渡效果的参数存储在样式中。可以设置以下过渡效果的属性
过渡时间 开始过渡之前的延迟时间 动画路径也称为定时或缓动函数 要进行动画的属性
过渡效果的属性可以针对每个状态进行定义。例如在默认状态下设置500毫秒的过渡时间意味着当对象转到默认状态时将应用500毫秒的过渡时间。在按下状态下设置100毫秒的过渡时间将导致在转到按下状态时应用100毫秒的过渡时间。这个例子的配置会使得快速转到按下状态然后缓慢返回到默认状态。
为了描述一个过渡效果需要初始化一个lv_transition_dsc_t变量并将其添加到一个样式中。
示例代码
static const lv_style_prop_t trans_props[] {LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR,0, /*End marker*/
};//要进行过渡效果的样式属性static lv_style_transition_dsc_t trans1;
/*对过渡效果结构体进行初始化。参数包括过渡效果结构体trans1、
要进行过渡的样式属性数组trans_props、动画路径lv_anim_path_ease_out表示渐出的动画路径、
过渡的持续时间duration_ms以毫秒为单位、过渡开始前的延迟时间delay_ms以毫秒为单位*/
lv_style_transition_dsc_init(trans1, trans_props, lv_anim_path_ease_out, duration_ms, delay_ms);lv_style_set_transition(style1, trans1);十一、主题
主题是一组样式的集合。如果有活动主题LVGL将其应用于每个创建的小部件。这将为UI提供一个默认外观然后可以通过添加更多样式进行修改。
每个显示屏可以具有不同的主题。例如您可以在TFT上使用彩色主题在辅助的单色显示器上使用单色主题。
要为显示屏设置主题需要两个步骤
初始化主题 将初始化的主题分配给显示屏。 主题初始化函数可以有不同的原型。此示例演示了如何设置“默认”主题。
lv_theme_t * th lv_theme_default_init(display, /*Use the DPI, size, etc from this display*/LV_COLOR_PALETTE_BLUE, LV_COLOR_PALETTE_CYAN, /*Primary and secondary palette*/false, /*Light or dark mode*/lv_font_montserrat_10, lv_font_montserrat_14, lv_font_montserrat_18); /*Small, normal, large fonts*/lv_display_set_theme(display, th); /*Assign the theme to the display*/lv_theme_default_init 是用于初始化默认主题的函数它有以下参数 display显示屏对象函数会使用该显示屏的 DPI每英寸点数、尺寸等信息进行初始化。 LV_COLOR_PALETTE_BLUE主题的主色调primary palette。这是一个蓝色调色板用于主题的基本颜色。 LV_COLOR_PALETTE_CYAN主题的次要色调secondary palette。这是一个青色调色板用于主题的其他颜色。 false用于指定主题的模式false 表示深色模式dark mode。 lv_font_montserrat_10用于指定主题中小号字体的字体对象。在这个例子中使用了 Montserrat 字体的 10 号字体。 lv_font_montserrat_14用于指定主题中正常号字体的字体对象。在这个例子中使用了 Montserrat 字体的 14 号字体。 lv_font_montserrat_18用于指定主题中大号字体的字体对象。在这个例子中使用了 Montserrat 字体的 18 号字体。 这些参数一起构成了一个主题对象该对象包含了显示屏的信息、颜色调色板、主题模式以及不同字体大小的字体对象。然后通过 lv_display_set_theme(display, th) 将这个主题分配给显示屏以便应用在创建的小部件上。
如果你使用的模拟器则display在这里: 如果不是模拟器则是在这创建的
lv_disp_t *display lv_disp_drv_register(disp_drv);如果在 lv_conf.h 文件中启用了包含的主题选项而且通过 LV_USE_THEME_DEFAULT 启用了默认主题LVGL 将在创建显示屏时自动进行初始化并设置默认主题。 总结
通过本文的 介绍我们深入了解了LVGL 9中Style样式的强大功能。从基本的颜色和边框设置开始我们学习了如何使用Style为界面元素定制各种视觉效果。我们还讨论了如何在运行时动态修改样式使得界面能够更灵活地适应不同的用户交互和应用状态。Style的灵活性为开发者提供了丰富的选择使他们能够创建出独特而富有吸引力的用户界面。通过巧妙地运用LVGL 9的Style样式开发者可以在GUI开发中取得更为出色的成果。