尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

HarmonyOs应用《重要日》开发第17篇 - 日历页多视图切换

HarmonyOs应用《重要日》开发第17篇 - 日历页多视图切换
📅 发布时间:2026/7/18 1:43:02

本文解析 ImportantDays 项目中的日历页面CalendarPage,包括年/月视图切换、日期导航(前后月、今天、日期选择器)、选中日期的重要日列表展示、以及日历与重要日数据的联动设计。

一、页面定位

CalendarPage是应用的第二个 Tab 页面,提供日历浏览功能。用户可以:

  1. 在年视图和月视图之间切换
  2. 左右滑动浏览不同月份/年份
  3. 点击日期查看当天的重要日
  4. 通过日期选择器快速跳转

二、组件定义

@ComponentV2exportstruct CalendarPage{vm:CalendarVM=CalendarVM.getInstance();manager:ImportantDayManager=ImportantDayManager.getInstance();@LocalcurrentTitle:string='';@LocalselectedDays:ImportantDay[]=[];@LocalshowDatePicker:boolean=false;}

状态变量

变量说明
vm日历视图模型单例
manager重要日管理器单例
currentTitle当前显示的标题(年/月)
selectedDays选中日期的重要日列表
showDatePicker日期选择器弹窗状态

三、生命周期

aboutToAppear():void{this.updateTitle();this.updateSelectedDays();}

页面即将出现时初始化标题和选中日期的重要日列表。

四、build 方法整体结构

build(){Column(){// 1. 标题栏(导航 + 今天按钮)Row(){...}// 2. 视图切换按钮Row(){...}// 3. 日历主体if(this.vm.viewType===ViewTypeEnum.YEAR){YearCalendar({...})}else{MonthWeekCalendar({...})}// 4. 选中日期的重要日列表if(this.selectedDays.length>0){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.selectDate=this.vm.selectDate.subtract(1,'month');this.updateTitle();})// 当前月份标题Text(this.currentTitle).fontSize(20).fontWeight(FontWeight.Bold).fontColor('#333333').layoutWeight(1).textAlign(TextAlign.Center).onClick(()=>{this.showDatePicker=true;})// 下个月按钮Text('>').fontSize(20).fontColor('#666666').padding(8).onClick(()=>{this.vm.selectDate=this.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.viewType===item.type?'#FFFFFF':'#666666').backgroundColor(this.vm.viewType===item.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.viewType===ViewTypeEnum.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})}

年视图回调

年视图中选择日期后:

  1. 更新 VM 选中日期
  2. 自动切换到月视图
  3. 更新标题和重要日列表

月视图回调

月视图中选择日期后:

  1. 更新选中日期的重要日列表
  2. 下方区域展示当天重要日

八、当日重要日列表

if(this.selectedDays.length>0){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.year&&value.month!==undefined&&value.day){constdate=dayjs().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.showDatePicker=false;})}}

DatePicker 配置

配置值说明
start2000-01-01可选最早日期
end2099-12-31可选最晚日期
selected当前选中日期初始显示日期

选择流程

  1. 用户滚动选择年/月/日
  2. onChange实时更新 VM 选中日期
  3. 点击"确定"关闭弹窗
  4. 标题和重要日列表自动更新

十、更新方法

privateupdateTitle():void{if(this.vm.viewType===ViewTypeEnum.YEAR){this.currentTitle=this.vm.getCurrentYearTitle();}else{this.currentTitle=this.vm.getCurrentMonthTitle();}}privateupdateSelectedDays():void{this.selectedDays=this.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的设计体现了以下原则:

  1. 多视图共存:年视图和月视图通过条件渲染切换
  2. 多维度导航:前后按钮 + 今天按钮 + 日期选择器
  3. 数据联动:日期选择自动更新重要日列表
  4. 条件渲染:无重要日时不显示列表区域
  5. 卡片差异化:日历页卡片比列表页更简洁
  6. 标题智能切换:根据视图类型显示年或月标题

日历页为用户提供了从宏观(年视图)到微观(月视图+当日重要日)的完整日历浏览体验。

相关新闻

  • React 2022生态全景:核心演进与开发实践
  • Dart定时器原理与应用实践指南
  • Python 3.8核心特性解析:海象运算符与性能优化

最新新闻

  • 重庆劳力士回收价格查询及各大回收平台实测排行(2026年7月最新) - 收的高名表回收平台
  • 2026 年现阶段,克孜勒苏柯尔克孜自治州知名的手摇密集柜工厂哪个好,别再买!这个老物件竟是最佳收纳神器 - 企业推荐管【认证】
  • JavaSwing实现仿微信PC版界面开发指南
  • 2026高频雷达液位计选型指南与实测分析
  • 如何让Steam下载完成后自动关机:智能下载管理终极解决方案
  • PCB高速设计中的阻抗计算与控制实践

日新闻

  • 宝珀中国官方售后服务中心|官方热线和维修地址权威信息声明(2026年7月更新) - 宝珀官方售后服务中心
  • # 2026年北京知识产权律师推荐怎么选?看这五点关键不踩雷 - 本地品牌推荐
  • 2026实测教程:生成的拼豆图纸不满意怎么修改才省事 - 省事研究所

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号