概述
平台炬芯,使用LVGL渲染UI界面,实现人机交互。本实例基于模拟器运行,可供参考。
比较传统写法,还有优化的空间。
1、Visual Studio 26版本

2、代码
cpp
/*
* Copyright (c) 2020 Actions Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file brightness_set_view.c
*/
#include <os_common_api.h>
#include <app_ui.h>
#include <view_stack.h>
/* picture idx */
enum {
IDX_PIC_BS_BRIGHTNESS_DOWN_BTN = 0,
IDX_PIC_BS_BRIGHTNESS_UP_BTN,
IDX_PIC_BS_COUNT,
};
/* picture */
const static uint32_t _pic_ids[] = {
PIC_BS_BRIGHTNESS_DOWN_BTN, PIC_BS_BRIGHTNESS_UP_BTN,
};
/* group picture idx */
enum {
IDX_PIC_BS_BRIGHTNESS_SLIDER_BG = 0,
IDX_PIC_BS_BRIGHTNESS_SLIDER_ICON,
IDX_PIC_BS_GROUP_COUNT,
};
/* group picture */
const static uint32_t _pic_group_ids[] = {
PIC_BS_BRIGHTNESS_SLIDER_BG, PIC_BS_BRIGHTNESS_SLIDER_ICON,
};
typedef struct brightness_set_view_data {
lv_obj_t *scr;
lv_obj_t *main_obj;
/* lvgl resource */
lvgl_res_scene_t res_scene; //场景
lvgl_res_group_t res_group; //资源组
lv_img_dsc_t img_dsc[IDX_PIC_BS_COUNT];
lv_img_dsc_t img_group_dsc[IDX_PIC_BS_GROUP_COUNT];
lv_font_t font;
/* user data */
lv_obj_t *bright_down_btn;
lv_obj_t *bright_up_btn;
lv_obj_t *bright_slider; // 滑动条主体
lv_obj_t *bright_speaker_icon; // 保存亮度图标引用
int current_brightness; // 新增:保存当前亮度值,用于联动
} brightness_set_view_data_t;
/* 滑动条值变化回调:同步当前亮度值(可选:可在此添加系统亮度设置逻辑) */
static void bright_slider_change_cb(lv_event_t *e)
{
brightness_set_view_data_t *data = lv_event_get_user_data(e);
if (!data || !data->bright_slider) return;
// 获取滑动条当前值,更新到data中
data->current_brightness = lv_slider_get_value(data->bright_slider);
SYS_LOG_INF("current_brightness: %d", data->current_brightness);
// 【可选】如果需要同步到系统亮度,添加这里:
// set_brightness(data->current_brightness);
}
/* 亮度- 按键回调:控制滑动条值减少 */
static void bright_down_btn_cb(lv_event_t *e)
{
brightness_set_view_data_t *data = lv_event_get_user_data(e);
if (!data || !data->bright_slider) return;
// 从滑动条获取当前值,减少5(步长可调整)
int bright = lv_slider_get_value(data->bright_slider);
if (bright > 0) {
data->current_brightness = (bright - 5) < 0 ? 0 : (bright - 5); // 同步到data->current_brightness
lv_slider_set_value(data->bright_slider, data->current_brightness, LV_ANIM_ON); // 带动画更新滑动条
SYS_LOG_INF("bright_down_btn: %d", data->current_brightness);
// 同步到系统亮度
// set_brightness(data->current_brightness);
}
}
/* 亮度+ 按键回调:控制滑动条值增加 */
static void bright_up_btn_cb(lv_event_t *e)
{
brightness_set_view_data_t *data = lv_event_get_user_data(e);
if (!data || !data->bright_slider) return;
// 从滑动条获取当前值,增加5(步长可调整)
int bright = lv_slider_get_value(data->bright_slider);
if (bright < 100) {
data->current_brightness = (bright + 5) > 100 ? 100 : (bright + 5); // 同步到data->current_brightness
lv_slider_set_value(data->bright_slider, data->current_brightness, LV_ANIM_ON); // 带动画更新滑动条
SYS_LOG_INF("bright_up_btn: %d", data->current_brightness);
// 【可选】同步到系统亮度
// os_audio_set_brightness(data->current_brightness);
}
}
static int _brightness_set_view_preload(view_data_t *view_data)
{
return lvgl_res_preload_scene_compact(SCENE_BRIGHENESS_SET_VIEW, NULL, 0, lvgl_res_scene_preload_default_cb_for_view,
(void *)SANAG_S7S_BRIGHENESS_SET_VIEW,
SANAG_STY_FILE, SANAG_RES_FILE, SANAG_STR_FILE);
}
static int _brightness_set_view_load_resource(view_data_t *view_data)
{
int ret;
// alloc data
brightness_set_view_data_t *data = app_mem_malloc(sizeof(*data));
if (!data) {
return -ENOMEM;
}
view_data->user_data = data;
memset(data, 0, sizeof(*data));
// 初始化默认亮度(比如50)
data->current_brightness = 50;
/* scene */
ret = lvgl_res_load_scene(SCENE_BRIGHENESS_SET_VIEW, &data->res_scene,
SANAG_STY_FILE, SANAG_RES_FILE, SANAG_STR_FILE);
SYS_LOG_INF("load scene ret=%d", ret);
if (ret < 0) {
SYS_LOG_ERR("SCENE_BRIGHENESS_SET_VIEW not found");
return -ENOENT;
}
/* load picture from scene */
ret = lvgl_res_load_pictures_from_scene(&data->res_scene, _pic_ids, data->img_dsc, NULL, IDX_PIC_BS_COUNT);
SYS_LOG_INF("load picture from scene ret=%d", ret);
if (ret < 0) {
SYS_LOG_ERR("load picture from scene failed");
goto out_exit;
}
/* load group from scene */
ret = lvgl_res_load_group_from_scene(&data->res_scene, RES_BS_BRIGHTNESS_SLIDER, &data->res_group);
SYS_LOG_INF("load group from scene ret=%d", ret);
if (ret < 0) {
SYS_LOG_ERR("load group from scene failed");
goto out_exit;
}
/* load pictures from group */
ret = lvgl_res_load_pictures_from_group(&data->res_group, _pic_group_ids, data->img_group_dsc, NULL, IDX_PIC_BS_GROUP_COUNT);
SYS_LOG_INF("load pictures from group ret=%d", ret);
if (ret < 0) {
SYS_LOG_ERR("load pictures from group failed");
goto out_exit;
}
// font
ret = LVGL_FONT_OPEN_DEFAULT(&data->font, DEF_FONT_SIZE_NORMAL);
SYS_LOG_INF("open_font ret=%d", ret);
if (ret < 0) {
goto out_exit;
}
return 0;
out_exit:
_brightness_set_view_unload_resource(view_data);
SYS_LOG_ERR("load resource failed, exit");
return ret;
}
static int _brightness_set_view_unload_resource(view_data_t *view_data)
{
brightness_set_view_data_t *data = view_data->user_data;
if (data) {
lvgl_res_unload_scene(&data->res_scene);
/* unload group */
lvgl_res_unload_group(&data->res_group);
/* unload picture */
lvgl_res_unload_pictures(data->img_dsc, IDX_PIC_BS_COUNT);
/* unload group picture */
lvgl_res_unload_pictures(data->img_group_dsc, IDX_PIC_BS_GROUP_COUNT);
/* close font */
LVGL_FONT_CLOSE(&data->font);
// 只删父容器,子控件自动销毁,杜绝重复删除崩溃
if (data->main_obj != NULL && lv_obj_is_valid(data->main_obj)) {
lv_obj_clean(data->main_obj);
data->main_obj = NULL;
}
data->bright_down_btn = NULL;
data->bright_up_btn = NULL;
data->bright_slider = NULL;
data->bright_speaker_icon = NULL;
data->scr = NULL;
/*
if (data->scr != NULL && lv_obj_is_valid(data->scr)) {
lv_obj_clean(data->scr);
data->scr = NULL;
}
if (data->bright_down_btn != NULL && lv_obj_is_valid(data->bright_down_btn)) {
lv_obj_clean(data->bright_down_btn);
data->bright_down_btn = NULL;
}
if (data->bright_up_btn != NULL && lv_obj_is_valid(data->bright_up_btn)) {
lv_obj_clean(data->bright_up_btn);
data->bright_up_btn = NULL;
}
if (data->bright_slider != NULL && lv_obj_is_valid(data->bright_slider)) {
lv_obj_clean(data->bright_slider);
data->bright_slider = NULL;
}
if (data->bright_speaker_icon != NULL && lv_obj_is_valid(data->bright_speaker_icon)) {
lv_obj_clean(data->bright_speaker_icon);
data->bright_speaker_icon = NULL;
}*/
// free data
app_mem_free(data);
view_data->user_data = NULL;
SYS_LOG_INF("ok\n");
} else {
lvgl_res_preload_cancel_scene(SCENE_BRIGHENESS_SET_VIEW);
}
lvgl_res_unload_scene_compact(SCENE_BRIGHENESS_SET_VIEW);
return 0;
}
static int _brightness_set_view_layout(view_data_t *view_data)
{
brightness_set_view_data_t *data = (brightness_set_view_data_t *)view_data->user_data;
data->scr = lv_disp_get_scr_act(view_data->display);
data->main_obj = lv_obj_create(data->scr);
if (!data->main_obj) {
SYS_LOG_ERR("create main obj failed");
goto fail_exit;
}
lv_obj_set_size(data->main_obj, DEF_UI_VIEW_WIDTH, DEF_UI_VIEW_HEIGHT);
// 亮度减按钮
data->bright_down_btn = lv_img_create(data->main_obj);
lv_img_set_src(data->bright_down_btn, &data->img_dsc[IDX_PIC_BS_BRIGHTNESS_DOWN_BTN]);
lv_obj_set_pos(data->bright_down_btn, 32, 214);
lv_obj_add_flag(data->bright_down_btn, LV_OBJ_FLAG_CLICKABLE);
lv_obj_set_user_data(data->bright_down_btn, data);
lv_obj_add_event_cb(data->bright_down_btn, bright_down_btn_cb, LV_EVENT_CLICKED, data);
// 亮度加按钮
data->bright_up_btn = lv_img_create(data->main_obj);
lv_img_set_src(data->bright_up_btn, &data->img_dsc[IDX_PIC_BS_BRIGHTNESS_UP_BTN]);
lv_obj_set_pos(data->bright_up_btn, 298, 214);
lv_obj_add_flag(data->bright_up_btn, LV_OBJ_FLAG_CLICKABLE);
lv_obj_set_user_data(data->bright_up_btn, data);
lv_obj_add_event_cb(data->bright_up_btn, bright_up_btn_cb, LV_EVENT_CLICKED, data);
// 1. 滑动条背景图片(最底层,保留原图)
lv_obj_t *bright_slider_bg = lv_img_create(data->main_obj);
lv_img_set_src(bright_slider_bg, &data->img_group_dsc[IDX_PIC_BS_BRIGHTNESS_SLIDER_BG]);
lv_obj_set_pos(bright_slider_bg, 30, 120);
// 2. 创建滑动条(覆盖在背景图上,尺寸匹配)
lv_obj_t *slider = lv_slider_create(data->main_obj);
lv_obj_set_size(slider, 320, 80);
lv_obj_set_pos(slider, 30, 120);
lv_slider_set_range(slider, 0, 100);
lv_slider_set_value(slider, data->current_brightness, LV_ANIM_OFF); // 初始化到默认亮度
// 滑动条样式优化(匹配设计图)
lv_obj_set_style_bg_opa(slider, LV_OPA_0, LV_PART_MAIN); // 隐藏默认底框
lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_INDICATOR); // 选中区域白色
lv_obj_set_style_bg_opa(slider, LV_OPA_100, LV_PART_INDICATOR); // 选中区域不透明
lv_obj_set_style_radius(slider, 40, LV_PART_INDICATOR); // 半圆角(80高→40圆角)
lv_obj_set_style_pad_all(slider, 0, LV_PART_INDICATOR); // 无内边距
lv_obj_set_style_bg_color(slider, lv_color_hex(0x333333), LV_PART_MAIN); // 未选中区域深灰
lv_obj_set_style_bg_opa(slider, LV_OPA_80, LV_PART_MAIN); // 未选中区域半透
lv_obj_set_style_radius(slider, 40, LV_PART_MAIN); // 整体圆角
lv_obj_set_style_border_width(slider, 0, LV_PART_MAIN); // 无边框
lv_obj_set_style_bg_opa(slider, LV_OPA_0, LV_PART_KNOB); // 隐藏默认滑块
lv_obj_set_style_size(slider, 0, LV_PART_KNOB); // 滑块尺寸为0
// 绑定滑动条值变化事件(拖动滑动条同步亮度值)
lv_obj_set_user_data(slider, data);
lv_obj_add_event_cb(slider, bright_slider_change_cb, LV_EVENT_VALUE_CHANGED, data);
// 3. 亮度图标(创建为main_obj的子对象,确保置顶不遮挡)
data->bright_speaker_icon = lv_img_create(data->main_obj);
lv_img_set_src(data->bright_speaker_icon, &data->img_group_dsc[IDX_PIC_BS_BRIGHTNESS_SLIDER_ICON]);
lv_obj_align_to(data->bright_speaker_icon, bright_slider_bg, LV_ALIGN_LEFT_MID, 30, 0); // 固定位置
lv_obj_move_foreground(data->bright_speaker_icon); // 强制置顶(核心:解决遮挡)
// 保存滑动条引用
data->bright_slider = slider;
return 0;
fail_exit:
_brightness_set_view_unload_resource(view_data);
return -ENOMEM;
}
static int _brightness_set_view_paint(view_data_t *view_data)
{
return 0;
}
static int _brightness_set_view_key(view_data_t *view_data)
{
ui_key_msg_data_t *key_data = (ui_key_msg_data_t *)view_data;
if (KEY_VALUE(key_data->event) == KEY_GESTURE_RIGHT) {
view_stack_pop();
key_data->done = true;
}
return 0;
}
int _brightness_set_view_handler(uint16_t view_id, uint8_t msg_id, void *msg_data)
{
view_data_t *view_data = msg_data;
SYS_LOG_INF("_brightness_set_view_handler: view_id=%d, msg_id=%d", view_id, msg_id);
switch (msg_id) {
case MSG_VIEW_PRELOAD:
return _brightness_set_view_preload(view_data);
case MSG_VIEW_LAYOUT:
if (_brightness_set_view_load_resource(view_data)) return -ENOENT;
return _brightness_set_view_layout(view_data);
case MSG_VIEW_DELETE:
return _brightness_set_view_unload_resource(view_data);
case MSG_VIEW_PAINT:
return _brightness_set_view_paint(view_data);
case MSG_VIEW_KEY:
return _brightness_set_view_key(view_data);
default:
return 0;
}
}
VIEW_DEFINE(brightness_set, _brightness_set_view_handler, NULL, NULL,
SANAG_S7S_BRIGHENESS_SET_VIEW, NORMAL_ORDER, UI_VIEW_LVGL,
DEF_UI_VIEW_WIDTH, DEF_UI_VIEW_HEIGHT);
3、运行结果

