【鸿蒙开发】自定义年月日周时分日历

import dayjs from 'dayjs';

@CustomDialog

export struct TimeDataDialog {

  controller ?: CustomDialogController

  dateMap:Map<string,string>= new Map();//键值对存储日期信息

  @State dateList:string[]=[] //只存储天

  @State hourList:string[]=[] //只存储小时

  @State minList:string[]=[] //只存分钟

  @Prop defaultTime: string; //默认值

  @State dayStr: string=''; //存储日期选中的信息

  @State DateSelect: number=0;

  @State HourSelect: number=0;

  @State minSelect: number=0;

  cancel: () => void = () => {

}

  confirm: (commitDate: string, showDate: string) => void = () => {

}

  aboutToAppear(): void {

    this.initDate(); //初始化日期

    this.initHour(); //初始化小时

    this.initMin(); //初始化分钟

  }

  //初始化日期

  initDate(){

    this.changeDateList('add')

    this.changeDateList('subtract')

    this.initDefaultTime()

  }

  // 初始化默认选中

  initDefaultTime(){

    if(!this.defaultTime) {

      this.DateSelect=20//如果没有默认时间可以默认选中当天

      return

    }

    const hour = dayjs(this.defaultTime).format("HH") //小时

    const min = dayjs(this.defaultTime).format("mm") //分钟

    let dayStr = dayjs(this.defaultTime).format("YYYY年M月D日")

    dayStr = dayStr + ' ' + this.weeks[dayjs(this.defaultTime).day()]

    const dayIndex =this.dateList.indexOf(dayStr)

    if(dayIndex>-1 ){

      this.dayStr=dayStr

      this.DateSelect=dayIndex

    }

    this.HourSelect = this.hourList.indexOf(hour) //选中 小时

    this.minSelect = this.minList.indexOf(min) //选中 小时

  }

  /**

  * 周列表*/

  weeks: string[] = [

    getContext().resourceManager.getStringSync(

      $r('app.string.leaveIndex20')

    ),

    getContext().resourceManager.getStringSync(

      $r('app.string.leaveIndex21')

    ),

    getContext().resourceManager.getStringSync(

      $r('app.string.leaveIndex22')

    ),

    getContext().resourceManager.getStringSync(

      $r('app.string.leaveIndex23')

    ),

    getContext().resourceManager.getStringSync(

      $r('app.string.leaveIndex24')

    ),

    getContext().resourceManager.getStringSync(

      $r('app.string.leaveIndex25')

    ),

    getContext().resourceManager.getStringSync(

      $r('app.string.leaveIndex26')

    ),

  ]

  // 处理数据 type: add 新增 subtract减少

  changeDateList(type:string,time?:string){

    for (let i = 0; i < 30; i++) {

      // 这里需要 注意 subtract 减少 是i+1否则数据有一天是重复的

      const futureDay =type=='add'? dayjs(time).add(i, 'day'):dayjs(time).subtract(i+1, 'day');

      const day = futureDay.format("YYYY-MM-DD")

      let title = futureDay.format('YYYY年M月D日')

      title = title + ' ' + this.weeks[futureDay.day()]

      this.dateMap.set(title, day)

      if(type=='add'){ //添加以后的时间

        this.dateList.push(title)

      }else{ //添加 以前的时间

        this.dateList.unshift(title)

      }

}

}

  // 时间

  initMin(){

    for (let i = 0; i < 12; i++) {

      const str = this.padZero(i*5)

      this.minList.push(str)

    }

}

  // 小时

  initHour(){

    for (let i = 0; i < 24; i++) {

      const str = this.padZero(i)

      this.hourList.push(str)

    }

}

  //补充0

  padZero(num:number) {

    return num.toString().padStart(2, '0');

  }

  // 提交数据

  onSubmit(){

    const day = this.dateMap.get(this.dayStr)

    const hour = this.hourList[this.HourSelect]

    const min = this.minList[this.minSelect]

    const dateTime  = `${day} ${hour}:${min}`

    const showTime = `${this.dayStr} ${hour}:${min}`

    this.confirm(dateTime, showTime) //回传日期到父组件

    this.controller?.close()

  }

  build() {

    Column(){

      Flex(){

        TextPicker({ range: this.dateList, selected: this.DateSelect})

          .width('50%')

          .canLoop(true)//不循环

          .divider({

            strokeWidth: 1,

            startMargin: 0,

            endMargin: 0,

            color:'#ececec'

          })

          .textStyle({color:'#777777', font: {size: 15, weight: 400}})

          .selectedTextStyle({color: '#0af', font: {size: 15, weight: 600}})

          .onChange((value: string | string[], index: number | number[]) => {

            this.dayStr=value as string

            if(index==(this.dateList.length-10)){ //当滚动到倒数第10个时开始加载后续20天的数据

              this.DateSelect=index as number

              const dayStr = this.dateList[this.dateList.length-1]

              const day= this.dateMap.get(dayStr) as string

              this.changeDateList('add',day) //添加以后的时间

            }

            if(index==10){ //当滚动第10个时开始加载前20天的数据

              const dayStr = this.dateList[0]

              const day= this.dateMap.get(dayStr) as string

              this.changeDateList('subtract',day) //添加以前的时间

              this.DateSelect=index as number +20

            }

          })

        //小时

        TextPicker({ range: this.hourList, selected: this.HourSelect  }).width('25%')

          .divider({

            strokeWidth: 1,

            startMargin: 0,

            endMargin: 0,

            color:'#ececec'

          })

          .textStyle({color:'#777777', font: {size: 15, weight: 400}})

          .selectedTextStyle({color: '#0af', font: {size: 15, weight: 600}})

          .onChange((value: string | string[], index: number | number[]) => {

            this.HourSelect=index as number

          })

        //分钟

        TextPicker({ range: this.minList, selected: this.minSelect  }).width('25%')

          .divider({

            strokeWidth: 1,

            startMargin: 0,

            endMargin: 0,

            color:'#ececec'

          })

          .textStyle({color:'#777777', font: {size:15, weight: 400}})

          .selectedTextStyle({color: '#0af', font: {size: 15, weight: 600}})

          .onChange((value: string | string[], index: number | number[]) => {

            this.minSelect=index as number

          })

      }

      // 按钮

      Row(){

        Button('取消', { type: ButtonType.Normal, stateEffect: true })

          .margin({right:6})

          .borderRadius(6)

          .backgroundColor('#fff')

          .fontColor('#0af')

          .borderWidth(1)

          .borderColor('#0af')

          .fontSize(15)

          .width(156)

          .onClick(()=>{

            this.controller?.close()

          })

        Button('确定', { type: ButtonType.Normal, stateEffect: true })

          .margin({left:6})

          .borderRadius(6)

          .fontSize(15)

          .backgroundColor('#0af')

          .width(156)

          .onClick(()=>{

            this.onSubmit()

            this.controller?.close()

          })

      }.justifyContent(FlexAlign.Center)

      .padding({top:15})

      .margin({top:25})

    }.width('100%')

    .padding(16)

    .backgroundColor('#fff')

    .borderRadius({topLeft:15,topRight:15})

  }

}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容