当前位置: 首页 > article >正文

在鸿蒙Next中开发一个月历组件

最近一直在出差,工作繁忙,很久没有时间更新文章了,连华为开发者大会也错过了。今天周末,忙里偷闲给大家分享一个鸿蒙月历组件。


这样的组件大家在工作中应该经常会遇到,而鸿蒙又没有提供一个这样的系统组件,今天我们就来看看怎么实现它。
标题部分比较简单,由两个箭头图片和一个文本组件构成,不再赘述。

下面的‘星期’部分有很多方式去实现,这里我选择使用弹性布局Flex:

@State WEEKS:string[] = ['周日','周一','周二','周三','周四','周五','周六']

Flex({direction:FlexDirection.Row,wrap:FlexWrap.NoWrap}){
          ForEach(this.WEEKS,(str:string,index)=>{
            Text(str)
              .fontSize(14)
              .fontColor(Color.Gray)
              .textAlign(TextAlign.Center)
              .width('50%')
              .height(35)
          })
        }



最难的部分在于日历部分,难点在于我们首先要知道当前月份一共有多少天,还要知道从星期几开始排列,也就是这个月的1号是星期几。
在鸿蒙中只需要一行代码就可以获取当前月份的总天数:
 

const totalDays = new Date(year, month, 0).getDate();



再获取1号是星期几:
 

currentFirstWeekDay = new Date(year, month - 1, 1).getDay();



接下来,为了方便展示数据,我们除了要把总天数存入数组以外,还要在1号前补0。比如某个月的第一天是星期三,我们就要在前面补两个0,或者你如果把周日放在第一天就要补3个0。

for (let item = 0; item < currentFirstWeekDay; item++) {
      currentAllDay.push(0)
}
for (let item = 1; item <= totalDays; item++) {
      currentAllDay.push(item);
}



在创建数组的过程,你还可以插入一些其他需要展示的信息。
有了上面的数组之后就可以很容易的展示它们,你可以选择Grid网格组件,也可以使用Flex弹性布局组件:
 

Flex({direction:FlexDirection.Row,wrap:FlexWrap.Wrap}){
          ForEach(this.MONTHDAY,(calendar:Calendar,index)=>{
            Column({space:2}){
              Text(calendar.day.toString())
                .fontSize(16)
                .fontColor(Color.Black)
                .textAlign(TextAlign.Center)
                .fontWeight(FontWeight.Bold)
                Text(calendar.content)
                  .fontColor(Color.Gray)
                  .fontSize(10)
            }
            .justifyContent(FlexAlign.Center)
            .padding({top:4})
            .width('14.2%')
            .height(60)
            .alignItems(HorizontalAlign.Center)
            .visibility(calendar.day == 0? Visibility.Hidden:Visibility.Visible)
            .backgroundColor(Color.White)
          })
        }


下面为大家贴出完整代码:

@Entry
@Component
struct Index {
  @State WEEKS:string[] = ['周日','周一','周二','周三','周四','周五','周六']
  @State MONTHDAY:Calendar[] = []
  @State dateToday:Date = new Date()
  @State monthNow:number = this.dateToday.getMonth() + 1
  @State yearNow:number = this.dateToday.getFullYear()
  
  aboutToAppear(){
    this.getMonthContent()
  }

  getMonthContent(){
    const monthDays: number[] = this.getMonthDate(this.monthNow, this.yearNow);
    this.MONTHDAY = []
    for (let index = 0; index < monthDays.length; index++) {
      const num = monthDays[index];
      let calendarItem:Calendar = {
        year:this.yearNow,
        month:this.monthNow,
        day:num,
        content:'内容 ' + (Math.floor(Math.random() * 10)).toString()
      }
      this.MONTHDAY.push(calendarItem)
    }
  }

  getMonthDate(month: number, year: number): number[] {
    const SATURDAY: number = 6;
    let currentFirstWeekDay: number = 0;
    let currentLastWeekDay: number = 0;
    const currentAllDay: number[] = [];
    const totalDays = new Date(year, month, 0).getDate();
    //最后-1表示星期从周一开始,周日开始则不需要
    currentFirstWeekDay = new Date(year, month - 1, 1).getDay();
    currentLastWeekDay = new Date(year, month - 1, totalDays).getDay();
    for (let item = 0; item < currentFirstWeekDay; item++) {
      currentAllDay[item] = 0;
    }
    for (let item = 1; item <= totalDays; item++) {
      currentAllDay.push(item);
    }
    for (let item = 0; item < SATURDAY - currentLastWeekDay; item++) {
      currentAllDay.push(0);
    }
    return currentAllDay;
  }

  addZreo(num:number){
    return num > 9?num.toString() : '0' + num.toString()
  }

  lastMonth(){
    if(this.monthNow > 0){
      this.monthNow -= 1
    }else {
      this.monthNow = 12
      this.yearNow -= 1
    }
    this.getMonthContent()
  }
  nextMonth(){
    if(this.monthNow < 12){
      this.monthNow += 1
    }else {
      this.monthNow = 1
      this.yearNow += 1
    }
    this.getMonthContent()
  }

  build() {
    Column(){
      Row({space:20}){
        Image($r('app.media.last'))
          .width(25)
          .height(25)
          .onClick(()=>{
            this.lastMonth()
          })
        Text(this.yearNow.toString() + '-' + this.addZreo(this.monthNow))
          .fontSize(15)
          .fontColor(Color.Black)
          .fontWeight(FontWeight.Bold)
        Image($r('app.media.next'))
          .width(25)
          .height(25)
          .onClick(()=>{
            this.nextMonth()
          })
      }
      .width('100%')
      .height(40)
      .justifyContent(FlexAlign.Center)

      Column(){
        Flex({direction:FlexDirection.Row,wrap:FlexWrap.NoWrap}){
          ForEach(this.WEEKS,(str:string,index)=>{
            Text(str)
              .fontSize(14)
              .fontColor(Color.Gray)
              .textAlign(TextAlign.Center)
              .width('50%')
              .height(35)
          })
        }
        Flex({direction:FlexDirection.Row,wrap:FlexWrap.Wrap}){
          ForEach(this.MONTHDAY,(calendar:Calendar,index)=>{
            Column({space:2}){
              Text(calendar.day.toString())
                .fontSize(16)
                .fontColor(Color.Black)
                .textAlign(TextAlign.Center)
                .fontWeight(FontWeight.Bold)
                Text(calendar.content)
                  .fontColor(Color.Gray)
                  .fontSize(10)
            }
            .justifyContent(FlexAlign.Center)
            .padding({top:4})
            .width('14.2%')
            .height(60)
            .alignItems(HorizontalAlign.Center)
            .visibility(calendar.day == 0? Visibility.Hidden:Visibility.Visible)
            .backgroundColor(Color.White)
          })
        }
      }
    }
    .backgroundColor(Color.White)
    .width('100%')
    .padding({left:10,right:10})
  }
}
export interface Calendar {
  month: number; // 月
  day: number; // 日
  year:number; // 年
  content: string; // 内容
}


http://www.kler.cn/a/591111.html

相关文章:

  • 蓝桥杯备考:DFS求最短路之字串变换
  • 【软考-架构】8.1、信息系统概述-生命周期
  • 6. 顺序表和链表*****
  • Web Component 教程(三):生命周期方法的触发时机与实际应用
  • vue中ref解析
  • 人工智能_大模型097_TRAE_AI开发工具_企业级项目开发---人工智能工作笔记0242
  • kali破解Pdf/execl/word
  • Linux的根目录全知道
  • 【从零开始学习计算机科学】软件工程(五)软件设计
  • div中使用placeholder
  • Ajax原理笔记
  • 基于SpringBoot+Vue的幼儿园管理系统+LW示例参考
  • JavaScript基础-获取元素
  • 基于大模型的慢性鼻窦炎全周期预测与治疗方案研究报告
  • react-native 踩坑
  • DIFY整合VideoLLaMA3使用图片理解
  • 远程访问家里电脑上部署的Stable diffusion - 免费篇
  • 部队仓储信息化手段建设:基于RFID、IWMS、RCS三大技术的仓储物流全链路效能优化方案
  • 设计模式(创建型)-抽象工厂模式
  • 【Pandas】pandas Series sparse