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 但是跑不了代码,里面有很多这种你项目里的。我这并没有