HarmonyOs应用《重要日》开发第17篇 - 日历页多视图切换
本文解析 ImportantDays 项目中的日历页面CalendarPage包括年/月视图切换、日期导航前后月、今天、日期选择器、选中日期的重要日列表展示、以及日历与重要日数据的联动设计。一、页面定位CalendarPage是应用的第二个 Tab 页面提供日历浏览功能。用户可以在年视图和月视图之间切换左右滑动浏览不同月份/年份点击日期查看当天的重要日通过日期选择器快速跳转二、组件定义ComponentV2exportstruct CalendarPage{vm:CalendarVMCalendarVM.getInstance();manager:ImportantDayManagerImportantDayManager.getInstance();LocalcurrentTitle:string;LocalselectedDays:ImportantDay[][];LocalshowDatePicker:booleanfalse;}状态变量变量说明vm日历视图模型单例manager重要日管理器单例currentTitle当前显示的标题年/月selectedDays选中日期的重要日列表showDatePicker日期选择器弹窗状态三、生命周期aboutToAppear():void{this.updateTitle();this.updateSelectedDays();}页面即将出现时初始化标题和选中日期的重要日列表。四、build 方法整体结构build(){Column(){// 1. 标题栏导航 今天按钮Row(){...}// 2. 视图切换按钮Row(){...}// 3. 日历主体if(this.vm.viewTypeViewTypeEnum.YEAR){YearCalendar({...})}else{MonthWeekCalendar({...})}// 4. 选中日期的重要日列表if(this.selectedDays.length0){Divider()Text(当日重要日)Scroll(){Column(){ForEach(this.selectedDays,(day){this.importantDayCard(day)})}}}}.bindSheet($$this.showDatePicker,this.datePickerBuilder(),{...})}布局层次Column ├── Row (标题栏) ├── Row (视图切换) ├── YearCalendar / MonthWeekCalendar (日历主体) └── [条件] 当日重要日列表 ├── Divider ├── Text (标题) └── Scroll → ForEach → importantDayCard五、标题栏与导航Row(){// 上个月按钮Text().fontSize(20).fontColor(#666666).padding(8).onClick((){this.vm.selectDatethis.vm.selectDate.subtract(1,month);this.updateTitle();})// 当前月份标题Text(this.currentTitle).fontSize(20).fontWeight(FontWeight.Bold).fontColor(#333333).layoutWeight(1).textAlign(TextAlign.Center).onClick((){this.showDatePickertrue;})// 下个月按钮Text().fontSize(20).fontColor(#666666).padding(8).onClick((){this.vm.selectDatethis.vm.selectDate.add(1,month);this.updateTitle();})// 今天按钮Text(今天).fontSize(14).fontColor(#FF6B6B).padding({left:8,right:8}).onClick((){this.vm.goToToday();this.updateTitle();this.updateSelectedDays();})}导航功能按钮功能上一月标题打开日期选择器下一月今天跳转到今天标题点击点击标题文字打开日期选择器用户可以快速选择目标日期。六、视图切换Row(){ForEach(this.getViewTypes(),(item:ViewTypeItem){Text(item.name).fontSize(13).fontColor(this.vm.viewTypeitem.type?#FFFFFF:#666666).backgroundColor(this.vm.viewTypeitem.type?#FF6B6B:#F5F5F5).borderRadius(12).padding({left:12,right:12,top:4,bottom:4}).margin({right:8}).onClick((){this.vm.changeViewType(item.type);this.updateTitle();})})}privategetViewTypes():ViewTypeItem[]{return[{type:ViewTypeEnum.YEAR,name:年},{type:ViewTypeEnum.MONTH,name:月}];}视图切换按钮[年] [月]选中状态白字红底未选中灰字灰底切换逻辑点击按钮 →vm.changeViewType(type)→ VM 切换视图并重置数据 →updateTitle()更新标题。七、日历主体渲染if(this.vm.viewTypeViewTypeEnum.YEAR){YearCalendar({vm:this.vm,onSelectDate:(date:Date){this.vm.changeDate(dayjs(date));this.vm.changeViewType(ViewTypeEnum.MONTH);this.updateTitle();this.updateSelectedDays();}})}else{MonthWeekCalendar({vm:this.vm,onChangeDay:(date:Date){this.updateSelectedDays();},selectedColor:#FF6B6B,startWeekday:this.vm.startWeekday,isShowHeader:true})}年视图回调年视图中选择日期后更新 VM 选中日期自动切换到月视图更新标题和重要日列表月视图回调月视图中选择日期后更新选中日期的重要日列表下方区域展示当天重要日八、当日重要日列表if(this.selectedDays.length0){Divider().color(#EEEEEE)Text(当日重要日).fontSize(14).fontWeight(FontWeight.Medium).fontColor(#333333).padding({left:12,top:8,bottom:4})Scroll(){Column(){ForEach(this.selectedDays,(day:ImportantDay){this.importantDayCard(day)})}.padding({left:12,right:12,bottom:12})}.layoutWeight(1)}条件渲染只有选中日期有重要日时才显示此区域避免空列表占用空间。重要日卡片BuilderimportantDayCard(day:ImportantDay){Row(){// 颜色条Column().width(4).height(40).backgroundColor(day.color).borderRadius(2).margin({right:8})Column(){Text(day.title).fontSize(15).fontWeight(FontWeight.Medium).fontColor(#333333).maxLines(1)Text(${DateUtil.getFullDateStr(day.targetDate)}·${day.getDisplayText()}).fontSize(12).fontColor(#999999).margin({top:2})}.layoutWeight(1)// 倒数/正数标签Text(day.isCountdown?倒数:正数).fontSize(10).fontColor(day.isCountdown?#FF6B6B:#4ECDC4).backgroundColor(day.isCountdown?#FFF0F0:#E8FAF8).borderRadius(4).padding({left:6,right:6,top:2,bottom:2})}.padding({top:8,bottom:8}).borderRadius(8).backgroundColor(#FAFAFA).margin({bottom:4})}卡片设计┌─┬───────────────────────────────┬──────┐ │ │ 妈妈生日 │ 倒数 │ │ │ 2026年08月15日 · 还有 29 天 │ │ └─┴───────────────────────────────┴──────┘ 4vp layoutWeight(1) auto比列表页的卡片更简洁细色条4vp 宽代替宽色条无操作按钮添加倒数/正数标签九、日期选择器BuilderdatePickerBuilder(){Column(){Text(选择日期).fontSize(18).fontWeight(FontWeight.Medium).padding(16)DatePicker({start:newDate(2000-01-01),end:newDate(2099-12-31),selected:this.vm.selectDate.toDate()}).onChange((value:DatePickerResult){if(value.yearvalue.month!undefinedvalue.day){constdatedayjs().year(value.year).month(value.month).date(value.day);this.vm.changeDate(date);this.updateTitle();this.updateSelectedDays();}}).width(100%).height(200)Button(确定).width(80%).height(40).backgroundColor(#FF6B6B).margin({top:16}).onClick((){this.showDatePickerfalse;})}}DatePicker 配置配置值说明start2000-01-01可选最早日期end2099-12-31可选最晚日期selected当前选中日期初始显示日期选择流程用户滚动选择年/月/日onChange实时更新 VM 选中日期点击确定关闭弹窗标题和重要日列表自动更新十、更新方法privateupdateTitle():void{if(this.vm.viewTypeViewTypeEnum.YEAR){this.currentTitlethis.vm.getCurrentYearTitle();}else{this.currentTitlethis.vm.getCurrentMonthTitle();}}privateupdateSelectedDays():void{this.selectedDaysthis.vm.getSelectedDateDays();}updateTitle根据当前视图类型生成不同标题年视图2026年月视图2026年07月updateSelectedDays从 VM 获取选中日期的重要日列表更新到selectedDays。十一、数据联动日期选择 → 列表更新用户点击日期 ↓ MonthWeekCalendar.onDateClick ↓ vm.changeDate(date) ↓ onChangeDay 回调 ↓ CalendarPage.updateSelectedDays() ↓ vm.getSelectedDateDays() ↓ ImportantDayManager.getDaysByDate(dateStr) ↓ selectedDays 更新 ↓ UI 自动刷新Local 变化月份切换 → 标题更新用户滑动 Swiper ↓ handleSwiperChange ↓ vm.selectDate 更新到新月份 ↓ CalendarPage 检测到月份变化 ↓ updateTitle() ↓ 标题更新十二、总结CalendarPage的设计体现了以下原则多视图共存年视图和月视图通过条件渲染切换多维度导航前后按钮 今天按钮 日期选择器数据联动日期选择自动更新重要日列表条件渲染无重要日时不显示列表区域卡片差异化日历页卡片比列表页更简洁标题智能切换根据视图类型显示年或月标题日历页为用户提供了从宏观年视图到微观月视图当日重要日的完整日历浏览体验。

相关新闻

LDO稳压器原理、设计与选型指南

LDO稳压器原理、设计与选型指南

1. LDO基础概念与核心特性低压差线性稳压器(Low Dropout Regulator,简称LDO)是现代电子系统中不可或缺的电源管理器件。作为一名从事电源设计十余年的工程师,我见证了这个领域从传统线性稳压器到高性能LDO的技术演进。LDO最显著的…

2026/11/3 22:34:43 阅读更多 →
Windows系统隐藏文件夹清理与C盘空间优化指南

Windows系统隐藏文件夹清理与C盘空间优化指南

1. Windows系统隐藏文件夹的清理指南每次打开资源管理器看到C盘飘红,相信不少Windows用户都会心头一紧。系统盘空间不足不仅会导致运行卡顿,更会影响软件更新和日常使用。其实Windows系统中暗藏了不少"空间杀手",它们往往躲在系统目…

2026/11/4 2:15:35 阅读更多 →
Spring Cloud Gateway核心架构与请求处理流程解析

Spring Cloud Gateway核心架构与请求处理流程解析

1. Spring Cloud Gateway 核心架构解析Spring Cloud Gateway作为Spring官方推出的第二代API网关,其核心设计哲学是"过滤器即一切"。与传统的Servlet Filter不同,它基于响应式编程模型构建,底层采用Netty作为通信框架。整个架构可以…

2026/11/3 16:29:42 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/4 1:35:24 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/3 10:57:27 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/3 11:35:49 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/4 6:23:50 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/3 10:47:27 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/3 10:57:33 阅读更多 →

日新闻

周新闻

月新闻