一、概述
表格由行、列和单元格构建而成。
单元格只能包含文本,即任何数值数据在显示前都必须转换为文本格式。
单元格不作为独立的对象存在,而是按需绘制,这就保持了较低的内存占用。
二、部件和样式
- LV_PART_MAIN:表格的背景。
- LV_PART_ITEMS:单个单元格。
三、相关函数
1、void lv_table_set_cell_value(lv_obj_t *obj, uint16_t row, uint16_t col, const char *txt)
设置特定单元格的文本值。
会在需要的时候自动添加新的行或列到表格中,以确保指定的行和列存在。
lv_obj_t *table = lv_table_create(lv_scr_act());
lv_obj_center(table);
lv_obj_set_size(table, 400, 300);
lv_table_set_cell_value(table, 0, 0, "Row 1, Col 1");
lv_table_set_cell_value(table, 0, 1, "Row 1, Col 2");
lv_table_set_cell_value(table, 1, 0, "Row 2, Col 1");
lv_table_set_cell_value(table, 1, 1, "Row 2, Col 2");
lv_table_set_cell_value(table, 2, 0, "Row 3, Col 1");
lv_table_set_cell_value(table, 2, 1, "Row 3, Col 2");
lv_table_set_col_width(table, 0, 250);
lv_table_set_col_width(table, 1, 150);
2、void lv_table_set_cell_value_fmt(lv_obj_t *obj, uint16_t row, uint16_t col, const char *fmt, ...)
向表格中的特定单元格设置格式化字符串作为其值。此函数接受可变数量的参数,类似于C语言中的
printf()
函数,可使用各种格式化选项来设置单元格的内容。
fmt
:类似于printf()
的格式化字符串。可以包含占位符,如%d
、%s
等,用于格式化变量。...
:可变参数列表,与fmt
字符串中的占位符相对应。例如,如果fmt
为"%d %s"
,则应提供两个参数,第一个是整数,第二个是字符串。如果指定的行或列不存在,此函数会自动扩展表格以添加新的行或列,确保指定的位置有效。
lv_obj_t *table = lv_table_create(lv_scr_act());
lv_obj_center(table);
lv_obj_set_size(table, 400, 300);
lv_table_set_cell_value(table, 0, 0, "Row 1, Col 1");
lv_table_set_cell_value(table, 0, 1, "Row 1, Col 2");
lv_table_set_cell_value(table, 1, 0, "Row 2, Col 1");
lv_table_set_cell_value(table, 1, 1, "Row 2, Col 2");
lv_table_set_cell_value(table, 2, 0, "Row 3, Col 1");
lv_table_set_cell_value(table, 2, 1, "Row 3, Col 2");
const char *name = "zhang san";
int age = 30;
lv_table_set_cell_value_fmt(table, 0, 0, "%s", name);
lv_table_set_cell_value_fmt(table, 0, 1, "%d", age);
lv_table_set_col_width(table, 0, 250);
lv_table_set_col_width(table, 1, 150);
3、void lv_table_add_cell_ctrl(lv_obj_t *obj, uint16_t row, uint16_t col, lv_table_cell_ctrl_t ctrl)
向指定的单元格添加控制标志。可以用它改变单元格的行为或外观。
- LV_TABLE_CELL_CTRL_MERGE_RIGHT:与右边单元格合并
- LV_TABLE_CELL_CTRL_TEXT_CROP:可能是单元格内的文本长度超过了单元格的宽度则裁剪文本(没有实验成功)
- LV_TABLE_CELL_CTRL_CUSTOM_1:自定义标识
- LV_TABLE_CELL_CTRL_CUSTOM_2
- LV_TABLE_CELL_CTRL_CUSTOM_3
- LV_TABLE_CELL_CTRL_CUSTOM_4
合并单元格:
lv_obj_t *table = lv_table_create(lv_scr_act());
lv_obj_center(table);
lv_obj_set_size(table, 400, 300);
lv_table_add_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
lv_table_set_cell_value(table, 0, 0, "hello wolrd");
lv_table_set_cell_value(table, 1, 0, "Row 2, Col 1");
lv_table_set_cell_value(table, 1, 1, "Row 2, Col 2");
lv_table_set_cell_value(table, 2, 0, "Row 3, Col 1");
lv_table_set_cell_value(table, 2, 1, "Row 3, Col 2");
lv_table_set_col_width(table, 0, 250);
lv_table_set_col_width(table, 1, 150);
官方示例有关于 LV_TABLE_CELL_CTRL_CUSTOM_1 用法的例子:
// 定义表中的项数量
#define ITEM_CNT 200
// 当表中的单元格需要绘制时调用的事件处理程序
static void draw_event_cb(lv_event_t * e)
{
lv_obj_t * obj = lv_event_get_target(e);
lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
// 如果当前绘制的是单元格部分...
if(dsc->part == LV_PART_ITEMS)
{
// 检查该单元格是否具有自定义控件LV_TABLE_CELL_CTRL_CUSTOM_1
bool chk = lv_table_has_cell_ctrl(obj, dsc->id, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
lv_draw_rect_dsc_t rect_dsc;
lv_draw_rect_dsc_init(&rect_dsc);
// 设置背景颜色:如果是被标记的单元格,则为主题的主要颜色;否则为淡灰色
rect_dsc.bg_color = chk ? lv_theme_get_color_primary(obj) : lv_palette_lighten(LV_PALETTE_GREY, 2);
rect_dsc.radius = LV_RADIUS_CIRCLE; // 设置圆角
// 计算复选框的位置
lv_area_t sw_area;
sw_area.x1 = dsc->draw_area->x2 - 50;
sw_area.x2 = sw_area.x1 + 40;
sw_area.y1 = dsc->draw_area->y1 + lv_area_get_height(dsc->draw_area) / 2 - 10;
sw_area.y2 = sw_area.y1 + 20;
// 绘制复选框的背景
lv_draw_rect(&sw_area, dsc->clip_area, &rect_dsc);
// 绘制复选框的勾选标记
rect_dsc.bg_color = lv_color_white();
if(chk) { // 如果单元格被标记
sw_area.x2 -= 2;
sw_area.x1 = sw_area.x2 - 16;
} else { // 如果单元格未被标记
sw_area.x1 += 2;
sw_area.x2 = sw_area.x1 + 16;
}
sw_area.y1 += 2;
sw_area.y2 -= 2;
lv_draw_rect(&sw_area, dsc->clip_area, &rect_dsc);
}
}
// 当表中的单元格值发生改变时调用的事件处理程序
static void change_event_cb(lv_event_t * e)
{
lv_obj_t * obj = lv_event_get_target(e);
uint16_t col, row; // 获取当前选中的单元格的行和列
lv_table_get_selected_cell(obj, &row, &col);
// 检查该单元格是否具有自定义控件LV_TABLE_CELL_CTRL_CUSTOM_1
bool chk = lv_table_has_cell_ctrl(obj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
// 根据单元格状态切换LV_TABLE_CELL_CTRL_CUSTOM_1标志
if(chk)
lv_table_clear_cell_ctrl(obj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
else
lv_table_add_cell_ctrl(obj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
}
/**
* 使用表创建一个非常轻量级的列表
*/
void lv_example_table_2(void)
{
// 监测内存使用情况
lv_mem_monitor_t mon1;
lv_mem_monitor(&mon1);
uint32_t t = lv_tick_get(); // 获取当前时间点
// 创建表对象
lv_obj_t * table = lv_table_create(lv_scr_act());
// 设置表的高度,使其可滚动
lv_obj_set_size(table, LV_SIZE_CONTENT, 200);
// 设置第一列的宽度
lv_table_set_col_width(table, 0, 150);
// 设置行数,避免频繁的内存重新分配
lv_table_set_row_cnt(table, ITEM_CNT);
// 设置列数
lv_table_set_col_cnt(table, 1);
// 移除单元格按下的样式,因为我们将自定义绘制
lv_obj_remove_style(table, NULL, LV_PART_ITEMS | LV_STATE_PRESSED);
// 填充表的数据
uint32_t i;
for(i = 0; i < ITEM_CNT; i++)
lv_table_set_cell_value_fmt(table, i, 0, "Item %d", i + 1);
// 对齐表对象至屏幕中心
lv_obj_align(table, LV_ALIGN_CENTER, 0, -20);
// 添加绘制结束事件处理程序
lv_obj_add_event_cb(table, draw_event_cb, LV_EVENT_DRAW_PART_END, NULL);
// 添加值改变事件处理程序
lv_obj_add_event_cb(table, change_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
// 再次监测内存使用情况
lv_mem_monitor_t mon2;
lv_mem_monitor(&mon2);
// 计算使用的内存
long unsigned int mem_used = mon1.free_size - mon2.free_size;
// 计算创建过程所花费的时间
unsigned int elaps = lv_tick_elaps(t);
// 创建标签显示创建信息
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text_fmt(label, "%d items were created in %u ms\n"
"using %lu bytes of memory",
ITEM_CNT, elaps, mem_used);
// 对齐标签至屏幕底部居中
lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, -10);
}
void lv_table_clear_cell_ctrl(lv_obj_t *obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl)
清除特定单元格的控制标志。
bool lv_table_has_cell_ctrl(lv_obj_t *obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl)
单元格是否包含特定的控制标志。