#HarmonyOS NEXT体验官# 日历组件详细日界面组件 原创

奥尼5354
发布于 2025-3-10 22:39
565浏览
0收藏

背景

原生UI没有提供日历相关的组件,于是手撸了详细页面的日程。一开始打算使用list加tab的方式来实现切换的效果,但是list的切换是没有办法确定当前展示的索引的,所以没有办法实现日历内容动态添加等效果。在业内大佬的指导下,使用了两个swiper组件分别实现周和日的切换,实现了想要的效果,如下:

 #HarmonyOS NEXT体验官# 日历组件详细日界面组件-鸿蒙开发者社区

代码

DayViewPage

/**
 *周天数
 */
import { DateUtil } from '../Utils/DateUtil';

const WEEKDAY_NUMBER = 7;

@Entry
@Component
struct DayViewPage {
  //日期Swiper控件索引
  @State ShowDayIndex: number = 0;
  //展示日期
  @State ShowDay: Date = new Date();
  //日期集合
  @State DayList: Array<Date> = new Array<Date>();
  //日期滑动前索引
  @State DayStartIndex: number = 0;
  //日期滑动后索引
  @State DayEndIndex: number = 0;
  //周Swiper控件索引
  @State ShowWeekIndex: number = 0;
  //周组件亮显索引
  @State WeekDayIndex: number = 0
  //周所有日期集合
  @State CalendarLists: Array<Array<Date>> = new Array<Array<Date>>();
  private _TimeNameList: string[] = ["日", "一", "二", "三", "四", "五", "六"]
  private weekSwiperController: SwiperController = new SwiperController();
  private daySwiperController: SwiperController = new SwiperController();

  @Builder
  OneDayBuilder(index: number, showDate: Date) {
    Column() {
      Text(this._TimeNameList[index])
        .fontSize(14)
        .margin({ bottom: 4 })
        .fontColor(this.WeekDayIndex === index ? "#1655ed" : (index == 0 || index == 6) ? "#818382" : Color.Black)
      Column() {
        Text(showDate.getDate().toString())
          .fontColor(this.WeekDayIndex === index ? Color.White : (index == 0 || index == 6) ? "#818382" : Color.Black)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
      }
      .backgroundColor(this.WeekDayIndex === index ? "#1655ed" : Color.White)
      .width(35)
      .height(35)
      .borderRadius(17)
      .justifyContent(FlexAlign.Center)
    }
    .justifyContent(FlexAlign.Center)
    .height("100%")
    .width('100%')
    .backgroundColor(Color.White)
    .borderWidth({ bottom: 2 })
    .borderColor("#f3f3f3")
    .onClick(() => {
      this.UpdateShowDayIndex(showDate)
    })
  }

  aboutToAppear(): void {
    //初始化今天的一周的前和后
    this.ShowDay = new Date();
    let thisWeek: Array<Date> = DateUtil.GetWeekDateList(this.ShowDay);
    let previousWeek: Array<Date> = DateUtil.GetWeekDateList(DateUtil.GetNextDay(thisWeek[0], -1));
    let nextWeek: Array<Date> = DateUtil.GetWeekDateList(DateUtil.GetNextDay(thisWeek[thisWeek.length-1], 1));
    this.CalendarLists.push(previousWeek, thisWeek, nextWeek);
    this.WeekDayIndex = this.ShowDay.getDay();
    this.DayList = previousWeek.concat(thisWeek.concat(nextWeek));
    this.ShowWeekIndex = 1;
    this.ShowDayIndex = WEEKDAY_NUMBER + this.WeekDayIndex;
  }

  build() {
    Column({ space: 5 }) {
      Swiper(this.weekSwiperController) {
        ForEach(this.CalendarLists, (item: Array<Date>, index) => {
          Grid() {
            ForEach(item, (oneDay: Date, dayIndex) => {
              GridItem() {
                this.OneDayBuilder(dayIndex, oneDay)
              }
            })
          }
          .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')
        })
      }
      .index(this.ShowWeekIndex)
      .width("100%")
      .height(65)
      .loop(false)
      .indicator(false)
      .onAnimationEnd((index) => {
        this.ShowWeekIndex = index;
        if (index === 0) {
          this.AddPreviousWeekDay();
        } else if (index == this.CalendarLists.length - 1) {
          this.AddNextWeekDay();
        }
        let tempShowDay: Date = this.CalendarLists[this.ShowWeekIndex][this.WeekDayIndex];
        this.UpdateShowDayIndex(tempShowDay);
      })
      .margin({ top: 20 })

      Swiper(this.daySwiperController) {
        ForEach(this.DayList, (oneDay: Date, dayIndex) => {
          Column() {
            Text(oneDay.toString())
              .fontSize(30)
          }
          .height("100%")
          .justifyContent(FlexAlign.Center)
        })
      }
      .loop(false)
      .index(this.ShowDayIndex)
      .width("100%")
      .indicator(false)
      .layoutWeight(1)
      .onAnimationStart((start, end, event) => {
        this.DayStartIndex = start;
      })
      .onAnimationEnd((end, event) => {
        this.DayEndIndex = end;
        this.DaySwitch();
      })
    }
    .height('100%')
    .width('100%')

  }

  /**
   * 日程切换事件
   */
  private DaySwitch() {
    if (this.DayStartIndex == this.DayEndIndex) {
      return;
    }
    //往右滑,临界值滑动,需要修改week的展示索引
    if (this.DayStartIndex > this.DayEndIndex) {
      this.WeekDayIndex--;
      if (this.WeekDayIndex == -1) {
        this.weekSwiperController.showPrevious();
        this.WeekDayIndex = WEEKDAY_NUMBER - 1;
        this.ShowDay = this.CalendarLists[this.ShowWeekIndex-1][this.WeekDayIndex];
      }
    }
    //往左滑,临界值滑动,需要修改week的展示索引
    else {
      this.WeekDayIndex++;
      if (this.WeekDayIndex == WEEKDAY_NUMBER) {
        this.weekSwiperController.showNext();
        this.WeekDayIndex = 0;
        this.ShowDay = this.CalendarLists[this.ShowWeekIndex+1][this.WeekDayIndex];
      }
    }

  }

  /**
   * 添加上一周
   */
  private AddPreviousWeekDay() {
    let previousWeek: Array<Date> = DateUtil.GetWeekDateList(DateUtil.GetNextDay(this.CalendarLists[0][0], -1));
    this.CalendarLists.unshift(previousWeek);
    this.weekSwiperController.changeIndex(1);
    this.ShowWeekIndex = 1;
    this.DayList = previousWeek.concat(this.DayList);
    this.UpdateShowDayIndex();
  }

  /**
   * 添加下一周
   */
  private AddNextWeekDay() {
    let nextWeek: Array<Date> =
      DateUtil.GetWeekDateList(DateUtil.GetNextDay(this.CalendarLists[this.CalendarLists.length - 1][WEEKDAY_NUMBER -
        1], 1));
    this.CalendarLists.push(nextWeek);
    this.DayList = this.DayList.concat(nextWeek);
    this.UpdateShowDayIndex()
  }

  /**
   * 更新显示日期
   * @param nwDate
   */
  private UpdateShowDayIndex(nwDate?: Date) {
    if (nwDate != undefined) {
      this.ShowDay = nwDate;
    }
    this.WeekDayIndex = this.ShowDay.getDay();
    let showDayIndex = this.DayList.findIndex(x =>
    x.getFullYear() == this.ShowDay.getFullYear() &&
      x.getMonth() == this.ShowDay.getMonth() &&
      x.getDate() == this.ShowDay.getDate());
    if (showDayIndex == -1) {
      return;
    }
    this.daySwiperController.changeIndex(showDayIndex, false);
  }
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.

DateUtil

export class DateUtil {
  /**
   * 通过一天获得一周的date集合
   * @param oneDay
   * @returns
   */
  public static GetWeekDateList(oneDay: Date): Array<Date> {
    let dataList: Array<Date> = [];
    let dayNumber: number = oneDay.getDay();
    for (let index = 0; index < 7; index++) {
      let tempDate: Date = new Date(oneDay);
      tempDate.setDate(tempDate.getDate() + (index - dayNumber));
      dataList.push(tempDate);
    }
    return dataList;
  }

  public static GetNextDay(oneDay: Date, index: number): Date {
    let tempDay: Date = new Date(oneDay);
    tempDay.setDate(tempDay.getDate() + index);
    return tempDay;
  }
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报


回复
    相关推荐