列表菜单
列表菜单是一个用于显示列表的菜单。通过改变不同的
菜单样式
, 可以实现不同风格的列表菜单,也支持用户自定义菜单样式。
属性
Property | Description |
---|---|
Menu | 菜单项列表 |
Menu Style | 菜单样式,支持 列表 圆弧 齿轮 和 自定义 |
Menu Image Zoom | 菜单项图片缩放比例 |
Is Snap | 是否吸附,启用后,滑动菜单松开后,会自动将临近center_y的菜单项吸附到center_y |
Top Margin | 顶部边距,菜单项列表拉到顶部时,菜单项距离顶部的距离 |
Bottom Margin | 底部边距,菜单项列表拉到底部时,菜单项距离底部的距离 |
Friction Factor | 摩擦系数,控制滑动后的减速速率 |
Snap Factor | 吸附系数,控制菜单项吸附到中心位置的速度和强度 |
Elastic Factor | 弹性系数,控制滚动到边界时的弹性回弹效果 |
Out Of Bound Factor | 溢出系数,控制菜单滑动超出有效范围时的阻尼大小 |
网格菜单
的 Menu
属性可以选择 在 菜单管理
中配置好的菜单项列表。具体使用参见菜单
样式属性
不同菜单样式,支持的属性不同,具体如下:
列表样式
圆弧样式
Property | Description |
---|---|
Radius | 圆弧半径 |
- 齿轮样式
Property | Description |
---|---|
Radius | 圆弧半径 |
- 自定义样式
Property | Description |
---|---|
Nop1 | 自定义属性1 |
Nop2 | 自定义属性2 |
Nop3 | 自定义属性3 |
Nop4 | 自定义属性4 |
顶部/底部边距
为了使菜单项显示更美观,可以根据每个菜单项(图片)的高度以及行间距来计算控件的总高度。计算公式如下:
控件高度 = 菜单项高度 × 可见菜单项数量 + 行间距 × (可见菜单项数量 - 1)
//eg:假设需要同时显示 5 个菜单项,每个菜单项的图片尺寸为 80×80,行间距为 10,则控件的高度为
控件高度 = 80 × 5 + 10 × (5 - 1) = 440
如果要让菜单项列表实现 LV_SCROLL_SNAP_CENTER
效果,则需要设置 Head Margin
和 Tail Margin
属性。
Head Margin = 菜单项高度 × 可见菜单项数量 / 2 + 行间距 × 可见菜单项数量 / 2 // 可见菜单项数量为奇数
Tail Margin = 菜单项高度 × 可见菜单项数量 / 2 + 行间距 × 可见菜单项数量 / 2 // 可见菜单项数量为奇数
//eg
Head Margin = 80 × 5 / 2 + 10 × 5 / 2 = 180
Tail Margin = 80 × 5 / 2 + 10 × 5 / 2 = 180
样式
Style | Part | Description |
---|---|---|
Padding Left | Main | 左内边距 |
Padding Right | Main | 右内边距 |
Padding Top | Main | 上内边距 |
Padding Bottom | Main | 下内边距 |
Padding Row | Main | 行内边距 |
Padding Column | Items | 列内边距 |
使用
- 菜单配置

列表
- 控件属性

- 仿真

圆弧
- 控件属性

- 仿真

齿轮
- 控件属性

- 仿真

自定义
在 自定义
样式中,设计阶段会以 列表
样式显示。
- 控件属性
点击 位置变换
按钮,可以编写 位置变换
回调函数的实现。

- 回调实现
int16_t transform_cb(lv_point_t * icon_pos, const lv_obj_t * menu, const lv_obj_t * btn)
{
icon_pos->x += 20; //菜单项向右移动20px
return LV_IMG_ZOOM_NONE / 2; //菜单项缩放比例为1/2
}
- 仿真

- 回调参考1
int16_t transform_cb(lv_point_t * icon_pos, const lv_obj_t * menu, const lv_obj_t * btn)
{
lv_coord_t width = lv_obj_get_width(menu);
lv_coord_t height = lv_obj_get_height(menu);
lv_coord_t y_center = icon_pos->y;
lv_coord_t y_diff = y_center - height / 2;
lv_coord_t radius = 400;
if (y_diff > 0) {
return LV_IMG_ZOOM_NONE;
}
y_diff = LV_ABS(y_diff);
if (y_diff >= radius) {
icon_pos->x = radius;
} else {
uint32_t x_sqr = radius * radius - y_diff * y_diff;
lv_sqrt_res_t res;
lv_sqrt(x_sqr, &res, 0x8000);
icon_pos->x = radius - res.i;
}
return LV_IMG_ZOOM_NONE;
}
- 仿真

- 回调参考2
#include "math.h"
#ifndef M_PI
#define M_PI 3.14159265358
#endif
int16_t transform_cb(lv_point_t * icon_pos, const lv_obj_t * menu, const lv_obj_t * btn)
{
lv_coord_t height = lv_obj_get_height(menu);
lv_coord_t y_center = icon_pos->y;
lv_coord_t y_diff = y_center - height / 2;
if (LV_ABS(y_diff) > height) {
return LV_IMG_ZOOM_NONE;
}
float radius = 300;
float sin_value = height / radius / 2.0f;
float angle_rad = asinf(sin_value);
float angle = angle_rad * 2.0f * 180.0f / M_PI;
float angle_diff = (y_diff / (float)height) * angle;
float angle_sin = sinf(angle_diff * M_PI / 180.0f);
float angle_cos = cosf(angle_diff * M_PI / 180.0f);
icon_pos->x = (lv_coord_t)(radius - radius * angle_cos);
icon_pos->y = (lv_coord_t)(height / 2 + radius * angle_sin);
icon_pos->x = 60 - icon_pos->x;
return LV_IMG_ZOOM_NONE;
}
- 仿真
