HarmonyOS 鸿蒙Next--自定义日历组件
HarmonyOS 鸿蒙Next–自定义日历组件
0、自定义日历组件,滑动切换月、双箭头切换年, 我这里用来记录每个月的打卡状况,可自定义修改
1、获取日历列表数据
import { DateUtil } from ‘@pura/harmony-utils’; import { CalendarInfoBean } from ‘…/viewmodel/work/types’;
const SATURDAY = 6 // 日历表上周六对应的序列号,从周日开始算起,取值0~6
export function getMonthDate(specifiedMonth: number, specifiedYear: number) { let currentFirstWeekDay: number = 0; // 初始化指定月的第一天是周几 let currentLastWeekDay: number = 0; // 初始化指定月的最后一天是周几 let currentAllDay: CalendarInfoBean[] = []; // 初始化指定月的日期排列数组 let totalDays = new Date(specifiedYear, specifiedMonth, 0).getDate(); // 初始化指定月总天数 let lastDays = new Date(specifiedYear, specifiedMonth - 1, 0).getDate(); // 初始化上月总天数 currentFirstWeekDay = new Date(specifiedYear, specifiedMonth - 1, 1).getDay() // 获取指定月的第一天是周几 currentLastWeekDay = new Date(specifiedYear, specifiedMonth - 1, totalDays).getDay() // 获取指定月的最后一天是周几
let currentDay = Number.parseInt(DateUtil.getTodayStr().substring(8, 10)); // 今天是几号
// 将月份中显示上个月日期的内容补全 for (let item = lastDays - currentFirstWeekDay + 1; item <= lastDays; item++) { currentAllDay.push(new CalendarInfoBean(specifiedYear + “”, specifiedMonth + “”, item + “”, 0, false, false)); } // 将本月日期内容存入数组 for (let item = 1; item <= totalDays; item++) { if (item === currentDay) { currentAllDay.push(new CalendarInfoBean(specifiedYear + “”, specifiedMonth + “”, item + “”, 1, true, true)); } else { currentAllDay.push(new CalendarInfoBean(specifiedYear + “”, specifiedMonth + “”, item + “”, 1, false, false)); } } // 将月份中显示下个月日期的内容补全 for (let item = 1; item < SATURDAY - currentLastWeekDay + 1; item++) { currentAllDay.push(new CalendarInfoBean(specifiedYear + “”, specifiedMonth + “”, item + “”, 2, false, false)); } return currentAllDay; }
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
1.1、CalendarInfoBean日历实体,可自定义添加需要的数据
@ObservedV2 export class CalendarInfoBean { year?: string; month?: string; day?: string; isCurrent?: number; // 0:上月,1:当月,2:下月 isCurrentDay?: boolean; // 是否是今天 @Trace isSelect?: boolean; // 是否选中 @Trace state?: string; // 打卡状态,0:一次未打卡,1:打了一次卡,2:打了两次卡
constructor(year: string, month: string, day: string, isCurrent: number, isCurrentDay: boolean, isSelect: boolean) { this.year = year; this.month = month; this.day = day; this.isCurrent = isCurrent; this.isCurrentDay = isCurrentDay; this.isSelect = isSelect; } }
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
2、日历组件:用Swiper实现左右切换一页的功能
import { R } from ‘@ohos/res’; import { DateUtil } from ‘@pura/harmony-utils’ import { Constants } from ‘…/…/constants/Constants’; import { HttpUrl } from ‘…/…/constants/HttpUrl’; import { getMonthDate } from ‘…/…/utils/CalendarUtils’ import { HttpUtils } from ‘…/…/utils/HttUtils’; import { HttpData, ParamsModel } from ‘…/…/viewmodel/types’; import { CalendarInfoBean, CalendarListBean, ClockListDTO, SignInTotalBean } from ‘…/…/viewmodel/work/types’; import { Image35, Text16fp3F8CFF, Text16fp838A8F, Text16fpBlack, Text16fpWhite, Text18fpBlack } from ‘…/styles/BaseExtend’;
@Component export struct CalendarView { private weeks: string[] = [“日”, “一”, “二”, “三”, “四”, “五”, “六”]; @State currentYear: number = 0 @State currentMonth: number = 0 @State clockList: ClockListDTO[] = [] @State countdownTime: number = 10; @State calendarMonth: CalendarInfoBean[] = []; @State calendarList: CalendarListBean[] = []; private swiperController: SwiperController = new SwiperController(); @State currentIndex: number = 0;
getSignInTotal() { let params: ParamsModel = { param: { “months”: this.currentYear + this.currentMonth, } } HttpUtils.post(HttpUrl.CLOCK_MONTH_INFO, params) .then((res) => { let c = JSON.parse(res) as HttpData<SignInTotalBean> if (c.code === 200) { this.clockList = c.data?.clockList as ClockListDTO[]; } }) }
aboutToAppear(): void { let toDay = DateUtil.getTodayStr() this.currentYear = Number.parseInt(toDay.substring(0, 4)) this.currentMonth = Number.parseInt(toDay.substring(5, 7))
<span class="hljs-keyword"><span class="hljs-keyword">for</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> year = <span class="hljs-number"><span class="hljs-number">2023</span></span>; year <= <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentYear; year++) { <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> month = <span class="hljs-number"><span class="hljs-number">13</span></span>; <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (year === <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentYear) { month = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentMonth } <span class="hljs-keyword"><span class="hljs-keyword">for</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> index = <span class="hljs-number"><span class="hljs-number">1</span></span>; index < month; index++) { <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> month = getMonthDate(index, year) as CalendarInfoBean[] <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.calendarList.push(<span class="hljs-keyword"><span class="hljs-keyword">new</span></span> CalendarListBean(year, index, month)) } } <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> current = getMonthDate(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentMonth, <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentYear) <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.clockList !== <span class="hljs-literal"><span class="hljs-literal">null</span></span> && <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.clockList !== <span class="hljs-literal"><span class="hljs-literal">undefined</span></span>) { <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.clockList.forEach((element, index) => { <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (element.dayTime !== <span class="hljs-literal"><span class="hljs-literal">null</span></span> && element.dayTime !== <span class="hljs-literal"><span class="hljs-literal">undefined</span></span>) { <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> day = <span class="hljs-built_in"><span class="hljs-built_in">Number</span></span>.parseInt(element.dayTime.split(<span class="hljs-string"><span class="hljs-string">"-"</span></span>)[<span class="hljs-number"><span class="hljs-number">2</span></span>]) <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> currentDay = current.find(obj => obj.day === day + <span class="hljs-string"><span class="hljs-string">""</span></span>) as CalendarInfoBean <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (currentDay !== <span class="hljs-literal"><span class="hljs-literal">null</span></span> && currentDay !== <span class="hljs-literal"><span class="hljs-literal">undefined</span></span>) { currentDay.state = element.satate } } }); } <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.calendarList.push(<span class="hljs-keyword"><span class="hljs-keyword">new</span></span> CalendarListBean(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentYear, <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentMonth, current)) <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentIndex = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.calendarList.length - <span class="hljs-number"><span class="hljs-number">1</span></span>
}
build() { Column() { Row() { Image(R.media.ic_arrow_left_double) .attributeModifier(new Image35()) .padding(R.float.vp10) .margin({ left: R.float.vp15 }) .onClick(() => { this.swiperController.changeIndex(this.currentIndex - 12) }) Image(R.media.ic_arrow_left) .attributeModifier(new Image35()) .padding(R.float.vp10) .onClick(() => { this.swiperController.showPrevious() }) Text(this.currentYear + “年” + this.currentMonth + “月”) .attributeModifier(new Text18fpBlack()) .layoutWeight(1) Image(R.media.ic_arrow_right) .attributeModifier(new Image35()) .padding(R.float.vp10) .onClick(() => { this.swiperController.showNext() }) Image(R.media.ic_arrow_right_double) .attributeModifier(new Image35()) .padding(R.float.vp10) .margin({ right: R.float.vp15 }) .onClick(() => { this.swiperController.changeIndex(this.currentIndex + 12) }) } .margin({ top: R.float.vp10, bottom: R.float.vp10 }) .width(Constants.FULL_PARENT)
Grid() { ForEach(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.weeks, (week: string) => { GridItem() { Text(week).attributeModifier(<span class="hljs-keyword"><span class="hljs-keyword">new</span></span> Text16fpBlack()) } }) }.columnsTemplate(<span class="hljs-string"><span class="hljs-string">'1fr 1fr 1fr 1fr 1fr 1fr 1fr'</span></span>) .height(<span class="hljs-string"><span class="hljs-string">"20vp"</span></span>) .margin({ left: R.float.vp5, right: R.float.vp5 }) Swiper(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.swiperController) { ForEach(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.calendarList, (gridItem: CalendarListBean) => { ListItem() { Grid() { ForEach(gridItem.item, (item: CalendarInfoBean, index: number) => { GridItem() { RelativeContainer() { Text(item.day) .attributeModifier(item.isCurrent === <span class="hljs-number"><span class="hljs-number">1</span></span> ? (item.isCurrentDay ? (item.isSelect ? <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> Text16fpWhite() : <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> Text16fp3F8CFF()) : <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> Text16fpBlack()) : <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> Text16fp838A8F()) .alignRules({ middle: { anchor: <span class="hljs-string"><span class="hljs-string">"__container__"</span></span>, align: HorizontalAlign.Center }, center: { anchor: <span class="hljs-string"><span class="hljs-string">"__container__"</span></span>, align: VerticalAlign.Center } }) .id(<span class="hljs-string"><span class="hljs-string">"tv_day"</span></span>) Row() { } .visibility(item.state !== <span class="hljs-literal"><span class="hljs-literal">undefined</span></span> ? Visibility.Visible : Visibility.None) .width(R.float.vp5) .height(R.float.vp5) .borderRadius(R.float.vp5) .alignRules({ middle: { anchor: <span class="hljs-string"><span class="hljs-string">"__container__"</span></span>, align: HorizontalAlign.Center }, center: { anchor: <span class="hljs-string"><span class="hljs-string">"tv_day"</span></span>, align: VerticalAlign.Bottom } }) .margin({ top: R.float.vp2 }) .backgroundColor(item.state !== <span class="hljs-literal"><span class="hljs-literal">undefined</span></span> ? (item.state === <span class="hljs-string"><span class="hljs-string">"1"</span></span> ? R.color.color_00B578 : item.state === <span class="hljs-string"><span class="hljs-string">"2"</span></span> ? R.color.color_FF8F1F : R.color.color_838A8F) : Color.Transparent) .id(<span class="hljs-string"><span class="hljs-string">"tv_dot"</span></span>) } .width(R.float.vp40) .height(R.float.vp40) .borderRadius(R.float.vp20) .onClick(() => { gridItem.item.forEach(element => { element.isSelect = <span class="hljs-literal"><span class="hljs-literal">false</span></span> }); item.isSelect = <span class="hljs-literal"><span class="hljs-literal">true</span></span> }) .borderColor((item.isSelect && !item.isCurrentDay) ? R.color.color_838A8F : Color.Transparent) .borderWidth(R.float.vp1) .backgroundColor((item.isCurrentDay && item.isSelect) ? R.color.color_3F8CFF : Color.Transparent) } }) } .columnsTemplate(<span class="hljs-string"><span class="hljs-string">'1fr 1fr 1fr 1fr 1fr 1fr 1fr'</span></span>) .rowsTemplate(gridItem.item.length === <span class="hljs-number"><span class="hljs-number">35</span></span> ? <span class="hljs-string"><span class="hljs-string">'1fr 1fr 1fr 1fr 1fr'</span></span> : <span class="hljs-string"><span class="hljs-string">'1fr 1fr 1fr 1fr 1fr 1fr'</span></span>) .height(<span class="hljs-string"><span class="hljs-string">"290vp"</span></span>) .margin({ left: R.float.vp5, right: R.float.vp5 }) } .width(Constants.FULL_PARENT ) }) } .autoPlay(<span class="hljs-literal"><span class="hljs-literal">false</span></span>) .indicator(<span class="hljs-literal"><span class="hljs-literal">false</span></span>) .loop(<span class="hljs-literal"><span class="hljs-literal">false</span></span>) .index(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.calendarList.length - <span class="hljs-number"><span class="hljs-number">1</span></span>) .onChange((index: number) => { <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentIndex = index <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentYear = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.calendarList[index].year <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentMonth = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.calendarList[index].month }) }.width(Constants.FULL_PARENT)
} }
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
关于HarmonyOS 鸿蒙Next–自定义日历组件的问题,您也可以访问:https://www.itying.com/category-93-b0.html 联系官网客服。
更多关于HarmonyOS 鸿蒙Next--自定义日历组件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
你好,源码方便发一下学习一下吗
更多关于HarmonyOS 鸿蒙Next--自定义日历组件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
这里就是全部源码了呀,还有什么地方有问题吗
好的,刚没看清楚
希望HarmonyOS能继续加强与其他应用的兼容性,让用户体验更加完美。
…/…/constants/HttpUrl 但是跑不了代码,里面有很多这种你项目里的。我这并没有