1 日歷控件
1.1 日歷背景
lv_calendar 是 LVGL(Light and Versatile Graphics Library)提供的標準 GUI 控件之一,用于顯示日歷視圖。它支持用戶查看某年某月的完整日歷,還可以實現點擊日期、標記日期、導航月份等操作。這個控件通常用于需要日期交互的場景,比如設置日期、查看計劃、日程簽到等。
1.2 主要功能特點
1.2.1 顯示標準公歷月份
-
支持自動計算每月天數(含閏年判斷)
-
支持周起始日自定義(默認周一)
1.2.2 日期選擇功能
-
支持用戶點擊單個日期進行選擇
-
支持回調事件獲取所選日期
1.2.3 高亮多個日期
-
可用于標記節假日、簽到、提醒等
-
設置高亮顏色以區分普通日期
1.2.4 當前日期標識
-
提供 today_date 屬性,用于高亮當天
-
可靈活設定實際系統日期
1.2.5 支持月份切換
-
可通過箭頭或下拉方式更換月份
-
提供 calendar_header_arrow 和 calendar_header_dropdown 兩種頭部風格
1.2.6 樣式高度可定制
-
通過 LV_PART_* 接口設置顏色、背景、字體
-
與 LVGL 樣式系統無縫集成,適配不同 UI 風格
2 常見函數
2.1 創建一個新的日歷控件
lv_calendar_create(lv_obj_t * parent)
作用:在指定父對象上創建一個新的日歷控件對象。
參數:
parent:父對象(如 lv_scr_act() 表示當前屏幕)
返回值:返回日歷對象 lv_obj_t *
lv_obj_t * calendar = lv_calendar_create(lv_scr_act());
2.2 設置“今天”的日期,用于高亮當前日期。
lv_calendar_set_today_date(lv_obj_t * calendar, uint16_t year, uint8_t month, uint8_t day)
作用:設置“今天”的日期,用于高亮當前日期。
使用場景:用于展示當前系統日期或突出顯示今天。
示例:
lv_calendar_set_today_date(calendar, 2025, 5, 17);
2.2 設定月份和年份
lv_calendar_set_showed_date(lv_obj_t * calendar, uint16_t year, uint8_t month)
作用:設置日歷當前顯示的月份和年份。
使用場景:初始化時顯示特定月份,或切換月份。
示例:
lv_calendar_set_showed_date(calendar, 2025, 5);
2.3 “高亮日期”
lv_calendar_set_highlighted_dates(lv_obj_t * calendar, const lv_calendar_date_t * dates, uint16_t date_num)
作用:設置一組“高亮日期”,通常用于標記簽到、提醒、節假日等。
參數:
dates:日期數組
date_num:日期數量
static lv_calendar_date_t marked_days[2] = {{2025, 5, 10},{2025, 5, 20}
};
lv_calendar_set_highlighted_dates(calendar, marked_days, 2);
2.4 獲取當前選中的日期
lv_res_t lv_calendar_get_pressed_date(const lv_obj_t * obj, lv_calendar_date_t * date);typedef struct {uint16_t year;uint8_t month;uint8_t day;
} lv_calendar_date_t;
作用:當用戶點擊某個日期時,獲取當前選中的日期。
返回值:返回一個指向 lv_calendar_date_t 的指針(包含年/月/日),如果沒有選中則返回 NULL。
配合事件使用:
void calendar_event_cb(lv_event_t* e) {lv_obj_t* calendar = lv_event_get_current_target(e);lv_calendar_date_t date;lv_res_t reult=lv_calendar_get_pressed_date(calendar,&date);if (reult ==LV_RES_OK) {lv_log("選擇日期:%d-%d-%d\n", date.year, date.month, date.day);}
}lv_obj_add_event_cb(calendar, calendar_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
2.5 添加“左右箭頭”頭部
lv_calendar_header_arrow_create(lv_obj_t * calendar)
作用:為日歷控件添加“左右箭頭”頭部,用于月份切換。
返回值:返回頭部對象
示例:
lv_obj_t * header = lv_calendar_header_arrow_create(calendar);
2.7 下拉框樣式”的年月選擇頭部
lv_calendar_header_dropdown_create(lv_obj_t * calendar)
作用:為日歷添加“下拉框樣式”的年月選擇頭部。
示例:
lv_calendar_header_dropdown_create(calendar);lv_obj_set_size(calendar, 200, 300);lv_obj_center(calendar);
3 綜合代碼
lv_obj_set_style_…() 系列函數 來為 lv_calendar 添加自定義顏色和風格(style)。以下是一個 增強版的日歷應用界面,它不僅有“日期確認”功能,還對日歷控件進行了美化:背景色、邊框、選中顏色、今日高亮等都可以設置。
// 保存選中的日期
static lv_calendar_date_t selected_date;
static bool has_selected_date = false;// 事件:點擊日歷某個日期
static void calendar_event_cb(lv_event_t* e)
{lv_obj_t* calendar = lv_event_get_current_target(e);// 獲取點擊的日期if (lv_calendar_get_pressed_date(calendar, &selected_date) == LV_RES_OK) {has_selected_date = true;printf("你點擊了日期: %04d-%02d-%02d\n", selected_date.year, selected_date.month, selected_date.day);}
}// 事件:點擊“確認按鈕”
static void confirm_btn_event_cb(lv_event_t* e)
{if (has_selected_date) {printf("你設置的日期是: %04d-%02d-%02d\n",selected_date.year, selected_date.month, selected_date.day);// 這里可以調用你自己的保存函數// save_date_to_config(selected_date);// 也可以彈出提示框或跳轉頁面}else {printf("請先選擇日期\n");}
}void create_calendar_setting_page(void)
{// 創建日歷lv_obj_t* calendar = lv_calendar_create(lv_scr_act());// 設置大小和位置lv_obj_set_size(calendar, 230, 200);lv_obj_center(calendar);// 設置今天日期(用于高亮)lv_calendar_set_today_date(calendar, 2025, 5, 17);// 設置當前顯示的日期lv_calendar_set_showed_date(calendar, 2025, 5);// 添加箭頭頭部切換月份lv_calendar_header_arrow_create(calendar);// 添加事件lv_obj_add_event_cb(calendar, calendar_event_cb, LV_EVENT_VALUE_CHANGED, NULL);// 🎨 設置風格:背景色、邊框、圓角lv_obj_set_style_bg_color(calendar, lv_palette_lighten(LV_PALETTE_BLUE, 3), 0);lv_obj_set_style_border_color(calendar, lv_palette_darken(LV_PALETTE_BLUE, 2), 0);lv_obj_set_style_border_width(calendar, 2, 0);lv_obj_set_style_radius(calendar, 10, 0);// 設置今天的高亮顏色lv_obj_set_style_bg_color(calendar, lv_palette_main(LV_PALETTE_RED), LV_PART_ITEMS | LV_STATE_PRESSED);lv_obj_set_style_bg_color(calendar, lv_palette_main(LV_PALETTE_GREEN), LV_PART_ITEMS | LV_STATE_CHECKED);lv_obj_set_style_text_color(calendar, lv_color_white(), LV_PART_ITEMS | LV_STATE_CHECKED);// 創建確認按鈕lv_obj_t* btn = lv_btn_create(lv_scr_act());lv_obj_set_size(btn, 100, 40);lv_obj_align(btn, LV_ALIGN_BOTTOM_MID, 0, -10);lv_obj_add_event_cb(btn, confirm_btn_event_cb, LV_EVENT_CLICKED, NULL);lv_obj_t* label = lv_label_create(btn);lv_label_set_text(label, "confirm");lv_obj_center(label);
}