OpenHarmony - 基于ArkUI框架实现日历应用( 二 )

实现过程日历一页显示42天,包括上个月、当前月、下个月的天数,上个月和下个月的日期显示灰色,点击日期显示选中效果 。
支持选择年份、月份,指定一个日期,获取当前月的天数,根据该月1号在一周中的第几天,获取上个月显示的天数,以及下个月显示的天数 。
获取上一个月的天数,根据指定月份的1号在一周的第几天 , 上月最大天数,计算出上个月天数,以object的形式添加到数组,以便区分,代码如下:
const prevMonthDays = [];//获取上个月最大天数let prevLastDay = new Date(year, month-1, 0).getDate();//获取某月1号所在一周的第几天let startWeek = new Date(year, month, 1).getDay();// 上个月的最大天数减去当前月1号所在一周的第几天for (let i = prevLastDay - startWeek + 1; i <= prevLastDay; i++) {prevMonthDays.push({date: new Date(year, month - 1, i),status: 'prev'});}获取下一个月的天数,根据当前月份的1号在一周的第几天,当前月份的最大天数,计算出下个月天数,以object的形式添加到数组,以便区分,代码如下:
const nextMonthDays = [];//获取下个月最大天数let curLastDay = new Date(year, month, 0).getDate();//获取当前月份1号在一周的第几天let startWeek = new Date(year, month, 1).getDay();//一页的天数减去当前月份的天数和上个月的天数for (let i = 1; i <= 42 - startWeek - curLastDay + 1; i++) {nextMonthDays.push({date: new Date(year, month + 1, i),status: 'next'});}获取当前月的天数,以object的形式添加到数组,以便区分 , 代码如下:
let curLastDay = new Date(year, month, 0).getDate();for (let i = 1; i <= curLastDay; i++) {curMonthDays.push({date: new Date(year, month, i),status: 'current'});}屏幕适配屏幕适配需要用到媒体查询的接口,可以根据设备参数,例如:屏幕分辨率、横竖屏切换来修改应用的样式 。
首先导入媒体查询模块:
import mediaquery from '@ohos.mediaquery'然后通过matchMediaSync接口设置媒体查询条件,并保存返回的条件监听句柄 , 例如:监听设备类型,横竖屏状态 。
//监听横竖屏状态private listener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(orientation: landscape)');//监听当前设备类型private deviceListener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('screen and (device-type: default)');定义触发回调函数,当匹配到媒体查询条件时会触发此回调函数 。
onOrientationChange = (mediaQueryResult) => {if (mediaQueryResult.matches) {this.calendarWidth = "70%"this.titleBarLeft = 80} else {this.calendarWidth = "100%"this.titleBarLeft = 20}}onDeviceTypeChange = (mediaQueryResult) => {if(mediaQueryResult.matches){this.titleBarLeftTop = 10this.weekHeight = 30this.pikerDialogHeight = 200console.log("onDeviceTypeChangedevice-type: default")}else{this.titleBarLeftTop = 40this.weekHeight = 50this.pikerDialogHeight = 280}}通过条件监听句柄去注册回调函数,在 aboutToAppear 组件初始化的时候执行注册,退出时销毁监听 。
//组件初始化aboutToAppear() {this.listener.on('change', this.onOrientationChange);} //组件销毁aboutToDisappear(){this.listener.off('change', this.onOrientationChange);}数据懒加载当列表加载的数据过大时,直接采用循环渲染方式,导致页面启动时间过长 , 可以使用LazyForEach组件进行数据的懒加载进行优化,按需加载数据并创建相应组件 。
定义一个类并实现IDataSource接口:
export class YearData implements IDataSource{private list: number[] = []private listener: DataChangeListenerconstructor(list: number[]) {this.list = list}totalCount(): number {return this.list.length}getData(index: number): any {return this.list[index]}getDatAIndex(data:any){return this.list.indexOf(data)}registerDataChangeListener(listener: DataChangeListener): void {this.listener = listener}unregisterDataChangeListener() {}}在页面中导入并使用 。
import { YearData } from '../datasource/YearData'private data: YearData = https://www.isolves.com/it/cxkf/ydd/hms/2024-01-16/new YearData([]) LazyForEach(this.data, (item: string) => {ListItem() {Row() {Text(item).fontSize(20).margin({ left: 10 })}}.onClick(() => {this.data.pushData('item value: ' + this.data.totalCount())})}, item => item)}总结日历应用实现在一页42个格子上显示上个月、当前月、下个月的日期,通过日历应用的开发了解到了ArkUI组件的一些用法,生命周期和数据的加载过程,对之后的应用开发有很大的帮助 。


推荐阅读