鸿蒙开发进阶:实现一个属于自己的日期选择器

前言

hello 大家好 我是无言。最近在开发一个鸿蒙项目,刚好遇到了一个自定义比较强,样式还挺不错的日期选择器需求,经过不断调试打磨,最终效果还不错,所以打算分享出来,给大家一些创意灵感。

主要实现的功能

  • 选中日期回传给父组件。
  • 根据父组件默认选中时间打开子组件弹窗回显日期。
  • 动态加载日期边滚动边加载后续数据提升性能。

实现效果先一睹为快。

实现过程

一、准备工作
  • 安装好最新DevEco Studio 开发工具,创建一个新的空项目。
  • 为了避免重复造轮子,所以时间处理工具我这里用了[dayjs]。

 

二、先把整个弹窗逻辑实现

  • 创建弹窗子组件文件 ets/components/TimeDateDialog.ets 下面代码建议着重看下添加注释的地方,是容易踩坑的地方,所以我都特别标注出来了。
//弹窗具体内容
@CustomDialog
struct CustomDialogDate {
  controller?: CustomDialogController
  @State dateList:string[]=['2024-01-11','2024-01-12','2024-01-13','2024-01-14','2024-01-15'] //只存储天
  @State hourList:string[]=['01','02','03','04','05'] //只存储小时
  @State minList:string[]=['05','10','15','20','25'] //只存分钟
  cancel: () => void = () => {
  }
  confirm: (data:string) => void = () => {
  }

  aboutToAppear(): void {

  }

  build() {
    Column() {
      Row(){
        Text('显示时间').fontSize(18)
      }.padding({ bottom:25 }).width('100%').justifyContent(FlexAlign.Center)
      // 滚动选中区域
      Flex(){
        // 时间
        Flex(){
          // 时间
          TextPicker({ range: this.dateList})
            .width('50%')
            .canLoop(false)//不循环
            .divider({
              strokeWidth: 1,
              startMargin: 0,
              endMargin: 0,
              color:'#ececec'
            })
            .textStyle({color:'#777777', font: {size: 15, weight: 400}})
            .selectedTextStyle({color: '#ffd96868', font: {size: 15, weight: 600}})
         TextPicker({ range: this.hourList }).width('25%')
            .divider({
              strokeWidth: 1,
              startMargin: 0,
              endMargin: 0,
              color:'#ececec'
            })
            .textStyle({color:'#777777', font: {size: 15, weight: 400}})
            .selectedTextStyle({color: '#ffd96868', font: {size: 15, weight: 600}})

          //分钟
          TextPicker({ range: this.minList}).width('25%')
            .divider({
              strokeWidth: 1,
              startMargin: 0,
              endMargin: 0,
              color:'#ececec'
            })
            .textStyle({color:'#777777', font: {size:15, weight: 400}})
            .selectedTextStyle({color: '#ffd96868', font: {size: 15, weight: 600}})

        }
      }
      // 按钮
      Row(){
        Button('取消', { type: ButtonType.Normal, stateEffect: true })
          .margin({right:6})
          .borderRadius(6)
          .backgroundColor('#fff')
          .fontColor('#ffd96868')
          .borderWidth(1)
          .borderColor('#ffd96868')
          .fontSize(15)
          .width(156)
          .onClick(()=>{
            this.controller?.close()
          })
        Button('确定', { type: ButtonType.Normal, stateEffect: true })
          .margin({left:6})
          .borderRadius(6)
          .fontSize(15)
          .backgroundColor('#ffd96868')
          .width(156)
          .onClick(()=>{
             this.confirm('回传信息给父组件')
            this.controller?.close()
          })
      }.justifyContent(FlexAlign.Center)
      .padding({top:15})
      .margin({top:25})
    }.width('100%')
    .padding(16)
    .backgroundColor('#fff')
    .borderRadius({topLeft:15,topRight:15})
  }
}

//定义controller对象 主要作用父子通信 父组件调用子组件方法 唤醒弹窗
export  class DialogDateController {
  ShowDialog = (value?: string) => {
  }
}

//弹窗控制逻辑
@Component
export  struct TimeDateDialog { //修改命名 注意前面加了 export 需要暴露组件
  private controller: DialogDateController = new DialogDateController();
  CustomDialogController: CustomDialogController | null =null ;
  @Prop defaultTime: string;
  cancel?: () => void
  confirm?: (data:string) => void = () => {
  }
  // 打开显示弹窗
  private async 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值