零知开源——STM32F4实现ILI9486显示屏UI界面系列教程(二):日历功能实现

 本教程将指导您在STM32F4平台上实现一个功能完善的日历应用,通过ILI9486电阻触摸屏提供直观的日期查看和交互体验。该日历应用是智能设备UI系统中的核心组件,具有以下核心功能:月份视图展示、流畅的交互体验、日期标记系统

目录

一、硬件连接(同电子书教程)

二、软件UI组件实现

三、零知IDE配置(同电子书教程)

四、演示效果

五、常见问题解决

六、总结与扩展


一、硬件连接(同电子书教程)

硬件连接方式与电子书阅读器完全一致,请参考系列教程(一)的硬件连接部分。显示屏直接插入零知增强板专用接口,无需额外连线。

直达链接:零知开源——STM32F4实现ILI9486显示屏UI界面系列教程(一):电子书阅读器功能

ILI9486扩展板显示屏及日历UI页面图:

二、软件UI组件实现

2.1 核心数据结构

// 静态变量用于存储触摸状态
static lv_point_t calendar_touch_start;
static lv_calendar_ext_t * calendar_cal_ext;

2.2 触摸事件处理

// 日历事件处理函数
static void calendar_event_cb(lv_obj_t * obj, lv_event_t event)
{
    if (event == LV_EVENT_PRESSED) {
        lv_indev_t * indev = lv_indev_get_act();
        if (indev) {
            lv_indev_get_point(indev, &calendar_touch_start);
        }
    }
    else if (event == LV_EVENT_RELEASED) {
        lv_indev_t * indev = lv_indev_get_act();
        lv_point_t touch_end;
        if (indev) {
            lv_indev_get_point(indev, &touch_end);
            lv_coord_t dx = touch_end.x - calendar_touch_start.x;
            
            // 滑动阈值判断
            if (abs(dx) > 30) {
                if (dx > 0) {
                    // 向右滑动:上个月
                    if (calendar_cal_ext->showed_date.month <= 1) {
                        calendar_cal_ext->showed_date.month = 12;
                        calendar_cal_ext->showed_date.year--;
                    } else {
                        calendar_cal_ext->showed_date.month--;
                    }
                } else {
                    // 向左滑动:下个月
                    if (calendar_cal_ext->showed_date.month >= 12) {
                        calendar_cal_ext->showed_date.month = 1;
                        calendar_cal_ext->showed_date.year++;
                    } else {
                        calendar_cal_ext->showed_date.month++;
                    }
                }
                lv_obj_invalidate(obj);
            }
        }
    }
}

2.3 初始化界面 

void show_app_calendar()
{
    lv_obj_t *win = create_app_win("Calendar");
    lv_coord_t hres = lv_disp_get_hor_res(NULL);
    lv_coord_t vres = lv_disp_get_ver_res(NULL);
    
    // 创建日历对象
    lv_obj_t * calendar = lv_calendar_create(win, NULL);
    lv_obj_set_size(calendar, hres - 40, vres - 100);
    lv_obj_align(calendar, NULL, LV_ALIGN_CENTER, 0, 10);
    
    // 设置当前日期
    lv_calendar_date_t today;
    today.year = 2025;
    today.month = 6;
    today.day = 18;
    lv_calendar_set_today_date(calendar, &today);
    lv_calendar_set_showed_date(calendar, &today);
    
    // 设置高亮日期(示例)
    static lv_calendar_date_t highlighted_dates[2];
    highlighted_dates[0].year = 2025;
    highlighted_dates[0].month = 6;
    highlighted_dates[0].day = 20;
    
    highlighted_dates[1].year = 2025;
    highlighted_dates[1].month = 6;
    highlighted_dates[1].day = 25;
    
    lv_calendar_set_highlighted_dates(calendar, highlighted_dates, 2);
    
    // 设置样式(可选)
    static lv_style_t style_today_box;
    lv_style_copy(&style_today_box, lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_TODAY_BOX));
    style_today_box.body.border.color = LV_COLOR_RED;
    style_today_box.body.border.width = 2;
    lv_calendar_set_style(calendar, LV_CALENDAR_STYLE_TODAY_BOX, &style_today_box);
    
    static lv_style_t style_highlighted_days;
    lv_style_copy(&style_highlighted_days, lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS));
    style_highlighted_days.text.color = LV_COLOR_BLUE;
    lv_calendar_set_style(calendar, LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS, &style_highlighted_days);
    
    // 保存日历扩展数据用于事件处理
    calendar_cal_ext = lv_obj_get_ext_attr(calendar);
    
    // 设置事件回调
    lv_obj_set_event_cb(calendar, calendar_event_cb);
    
    // 添加滑动提示文本
    lv_obj_t * hint_label = lv_label_create(win, NULL);
    lv_label_set_text(hint_label, "Swipe left/right to change month");
    lv_obj_align(hint_label, calendar, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
    lv_obj_set_style(hint_label, &lv_style_plain_color);
}

2.4 功能说明

  • 通过左右滑动实现自然流畅的月份切换
  • 可标记重要日期(如会议、生日)
  • 当前日期有特殊红色边框标识
  • 触摸日期时有视觉反馈效果

三、零知IDE配置(同电子书教程)

请参考系列教程(一)的零知IDE配置部分,确保:

  • 正确配置LCD屏幕驱动
  • 启用触摸屏支持
  • 添加LVGL库依赖

四、演示效果

4.1 功能演示

  • 主界面点击日历图标进入应用

  • 查看当前月份日期布局

  • 左右滑动切换不同月份

  • 点击查看高亮日期的详细信息

4.2 视频效果

STM32F4驱动ILI9486实现日历功能

日历界面显示当前月份,高亮日期为蓝色,今日有红色边框

4.3 性能指标

项目数值说明
月份切换响应< 80ms从滑动到页面刷新的时间
内存占用38KB包括LVGL和日历数据
刷新率40Hz日历界面刷新频率
触摸精度±2像素日期选择精度

五、常见问题解决

5.1 日期显示错位

解决方案

// 在日历创建后添加布局刷新
lv_obj_refresh_ext_draw_pad(calendar);

5.2 滑动不灵敏

优化方案

// 降低滑动检测阈值(原30像素改为20像素)
if (abs(dx) > 20) { 
    // 月份切换逻辑
}

5.3 高亮日期不显示

检查步骤

  • 确认日期格式正确:{年, 月, 日}
  • 检查高亮日期数组大小匹配

  • 验证样式是否正确应用:

// 调试打印当前样式
lv_style_t *style = lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS);
Serial.printf("Text color: %d\n", style->text.color.full);

六、总结与扩展

6.1 实现总结

本教程实现了日历的核心功能:

  • 直观的月份/日期展示

  • 流畅的滑动切换体验

  • 重要日期标记功能

  • 实时日期显示集成

6.2 扩展建议 

//1.添加事件提醒
typedef struct {
    lv_calendar_date_t date;
    char event[32]; // 事件描述
} CalendarEvent;

//2.周视图切换
lv_obj_t *btn_switch = lv_btn_create(win, NULL);
lv_obj_set_event_cb(btn_switch, switch_view_cb);

//农历支持
const char* get_lunar_date(uint8_t month, uint8_t day);

6.3 下一步

在下一个系列教程中,我们将实现记事本键盘和显示功能。

 ▶零知实验室 - 让嵌入式开发更简单:
www.lingzhilab.comhttp://www.lingzhilab.com/

零知开源是真正属于国人自己的开源平台,提供了完整的开发教程和丰富的示例代码。通过本系列教程,您已经掌握了电子书阅读器和日历功能的实现方法。立即动手尝试,创造更多精彩应用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值