HarmonyOS NEXT应用开发案例—自定义日历选择器
介绍
本示例介绍通过CustomDialogController类显示自定义日历选择器。
效果图预览

使用说明
- 加载完成后显示主界面,点当前日期后会弹出日历选择器,选择日期后会关闭弹窗,主页面日期会变成选定的日期。
实现思路
- 获取当前月和下个月的日期信息。源码参考GetDate.ets。
const SATURDAY = 6 // 日历表上周六对应的序列号,从周日开始算起,取值0~6
export function getMonthDate(specifiedMonth: number, specifiedYear: number) {
  let currentFirstWeekDay: number = 0; // 初始化指定月的第一天是周几
  let currentLastWeekDay: number = 0; // 初始化指定月的最后一天是周几
  let currentAllDay: number[] = []; // 初始化指定月的日期排列数组
  let totalDays = new Date(specifiedYear, specifiedMonth, 0).getDate(); // 初始化指定月总天数
  currentFirstWeekDay = new Date(specifiedYear, specifiedMonth - 1, 1).getDay() // 获取指定月的第一天是周几
  currentLastWeekDay = new Date(specifiedYear, specifiedMonth - 1, totalDays).getDay() // 获取指定月的最后一天是周几
  // 将月份中显示上个月日期的内容置0
  for (let item = 0; item < currentFirstWeekDay; item++) {
    currentAllDay[item] = 0;
  }
  // 将本月日期内容存入数组
  for (let item = 1; item <= totalDays; item++) {
    currentAllDay.push(item);
  }
  // 将月份中显示下个月日期的内容置0
  for (let item = 0; item < SATURDAY - currentLastWeekDay; item++) {
    currentAllDay.push(0);
  }
  return currentAllDay;
}
- 通过CustomDialogController类初始化自定义日历弹窗。源码参考CalendarView.ets。
dialogController: CustomDialogController = new CustomDialogController({
  builder: CustomCalendarPickerDialog({
    date: this.date,
    currentMonth: this.currentMonth,
    currentDay: this.currentDay,
    currentWeekDay: this.currentWeekDay,
    currentYear: this.currentYear,
    cancel: this.onCancel
  }),
  alignment: DialogAlignment.Bottom, // 自定义弹窗底端对齐
  customStyle: true // 弹窗样式自定义
})
- 设置自定义日历选择器界面。源码参考CustomCalendarPickerDialog.ets。
// 每个月的日期
List() {
  /*
   *性能知识点:列表中数据较多且不确定的情况下,使用LazyForEach进行数据循环渲染。
   *当组件滑出可视区域外时,框架会进行组件销毁回收以降低内存占用。
   *文档参考链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-rendering-control-lazyforeach-0000001524417213-V2
   */
  LazyForEach(this.contentData, (monthItem: Month) => {
    // 设置ListItemGroup头部组件,显示年份和月份
    ListItemGroup({ header: this.itemHead(monthItem.month) }) {
      ListItem() {
        Stack() {
          Text(monthItem.num.toString())
            .fontSize($r('app.integer.month_text'))
            .fontColor($r('app.color.ohos_id_color_palette_aux8'))
            .opacity(MONTH_OPACITY)
          Grid() {
            ForEach(monthItem.days, (day: number) => {
              GridItem() {
                Text(day.toString())
                  .fontSize($r('app.string.ohos_id_text_size_headline'))
                  .fontColor(day < this.currentDay && monthItem.num ===
                  this.currentMonth ? $r('app.color.ohos_id_color_text_secondary') : $r('app.color.ohos_id_color_text_primary'))
              }
              .borderRadius($r('app.string.ohos_id_corner_radius_default_m'))
              .backgroundColor(day === this.currentDay && monthItem.num ===
              this.currentMonth ? $r('app.color.ohos_id_color_palette9') : $r('app.color.ohos_id_color_background'))
              .opacity(day === 0 ? 0 : 1) // 将日期数组中为0的都设置为不显示,即不显示上个月和下个月的内容
              // 点击选定的日期后,关闭日历弹窗,显示日期改变为选择的日期
              .onClick(() => {
                if (day != 0) {
                  let weekIndex = monthItem.days.indexOf(day) % WEEK_NUMBER; // 将当前日转换成星期显示
                  this.date = [monthItem.num, day, weekIndex];
                  this.controller.close(); // 关闭自定义弹窗
                }
              })
            })
          }
          .backgroundColor($r('app.color.ohos_id_color_background'))
          .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')
          // 当前月显示的数组元素个数大于35则显示6行,否则显示5行
          .rowsTemplate(monthItem.days.length > MONTH_NUMBER ? '1fr 1fr 1fr 1fr 1fr 1fr' : '1fr 1fr 1fr 1fr 1fr')
          .height(monthItem.days.length > MONTH_NUMBER ? GRID_HEIGHT_L : GRID_HEIGHT_M)
        }
      }
    }
  })
}
高性能知识点
本示例使用了LazyForEach进行数据懒加载,List布局时会根据可视区域按需创建ListItem组件,并在ListItem滑出可视区域外时销毁以降低内存占用。 LazyForEach:数据懒加载
工程结构&模块类型
customcalendarpickerdialog                      // har类型
|---components
|   |---GetDate.ets                             // 获取日期信息
|   |---MonthDataSource.ets                     // 数据类型定义
|---view
|   |---CustomCalendarPickerDialog.ets          // 视图层-自定义日历
|   |---CalendarView.ets                        // 视图层-场景主页面
模块依赖
本实例依赖common模块来实现资源的调用。
参考资料
写在最后
- 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新VIP学习资源,请移步前往小编:https://qr21.cn/FV7h05
HarmonyOS NEXT应用开发案例—自定义日历选择器的更多相关文章
- iOS开发之自定义日历控件
		前言 日常开发中经常会遇到日期选择,为了方便使用,简单封装了一个日历控件,在此抛砖引玉供大家参考. 效果 功能 支持单选.区间 支持默认选中日期 支持限制月份 支持过去.当前.未来模式 支持frame ... 
- Android开发案例 - 自定义虚拟键盘
		所有包含IM功能的App(如微信, 微博, QQ, 支付宝等)都提供了Emoji表情之类的虚拟键盘, 如下图: 本文只着重介绍如何实现输入法键盘和自定义虚拟键盘的流畅切换, 而不介绍如何实现虚 ... 
- 大数据技术之_09_Flume学习_Flume概述+Flume快速入门+Flume企业开发案例+Flume监控之Ganglia+Flume高级之自定义MySQLSource+Flume企业真实面试题(重点)
		第1章 Flume概述1.1 Flume定义1.2 Flume组成架构1.2.1 Agent1.2.2 Source1.2.3 Channel1.2.4 Sink1.2.5 Event1.3 Flum ... 
- 原生js日历选择器,学习js面向对象开发日历插件
		在web开发过程中经常会碰到需要选择日期的功能,一般的操作都是在文本框点击,然后弹出日历选择框,直接选择日期就可以在文本框显示选择的日期.开发好之后给用户使用是很方便,但如果每一个日历选择器都要临时开 ... 
- javascript实例学习之六—自定义日历控件
		基于之前上篇博客轻量级jquery,tool.js和base.js.自定义开发的base_datePicker插件,效果类似于jquery_ui的datePicker插件 //基于Base.js以及t ... 
- 百度UEditor开发案例(JSP)
		本案例的开发环境:MyEclipse+tomcat+jdk 本案例的开发内容: 用百度编辑器发布新闻(UEditor的初始化开发部署) 编辑已发过的新闻(UEditor的应用——编辑旧文章) ... 
- 《实战突击:PHP项目开发案例整合(第2版)(含DVD光盘1张)》
		<实战突击:PHP项目开发案例整合(第2版)(含DVD光盘1张)> 基本信息 作者: 徐康明 辛洪郁 出版社:电子工业出版社 ISBN:9787121221378 上架时间:2014 ... 
- 前端到后台ThinkPHP开发整站--php开发案例
		前端到后台ThinkPHP开发整站--php开发案例 总结 还是需要做几个案例,一天一个为佳,那样才能做得快. 从需求分析着手,任务体系要构建好,这样才能非常高效. 转自: 前端到后台ThinkPHP ... 
- 自定义 Button 选择器
		极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ... 
- HarmonyOS三方件开发指南(13)-SwipeLayout侧滑删除
		鸿蒙入门指南,小白速来!0基础学习路线分享,高效学习方法,重点答疑解惑--->[课程入口] 目录:1. SwipeLayout组件功能介绍2. SwipeLayout使用方法3. SwipeLa ... 
随机推荐
- FreeRTOS教程4 消息队列
			1.准备材料 正点原子stm32f407探索者开发板V2.4 STM32CubeMX软件(Version 6.10.0) Keil µVision5 IDE(MDK-Arm) 野火DAP仿真器 XCO ... 
- MySQL 如何以当前日期时间作为字段初始默认值?
			1.以当前时间作为默认值 使用 DEFAULT CURRENT_TIMESTAMP 声明字段,插入记录时不用指定 dt,自动置入当前时间 CREATE TABLE t1 ( dt DATETIME D ... 
- .Net实现Html保存到照片
			本文将使用PuppeteerSharp组件.实现Html代码片段生成Jpg照片 PuppeteerSharp项目地址:https://github.com/hardkoded/puppeteer-sh ... 
- Cesium渲染模块之FBO与RBO
			1. 引言 Cesium是一款三维地球和地图可视化开源JavaScript库,使用WebGL来进行硬件加速图形,使用时不需要任何插件支持,基于Apache2.0许可的开源程序,可以免费用于商业和非商业 ... 
- 记录--组件库的 Table 组件表头表体是如何实现同步滚动?
			这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 在使用 Vue 3 组件库 Naive UI 的数据表格组件 DataTable 时碰到的问题,NaiveUI 的数据表格组件 Da ... 
- c# 正则提取内容例子
			分类 代码/语法 说明 捕获 (exp) 匹配exp,并捕获文本到自动命名的组里 (?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp) ... 
- Gaussian YOLOv3 : 对bbox预测值进行高斯建模输出不确定性,效果拔群 | ICCV 2019
			在自动驾驶中,检测模型的速度和准确率都很重要,出于这个原因,论文提出Gaussian YOLOv3.该算法在保持实时性的情况下,通过高斯建模.损失函数重建来学习bbox预测值的不确定性,从而提高准确率 ... 
- Scala编译原理
			1 package com.atguigu.chapter01; 2 /** 3 * 4 */ 5 //main 方法名 6 //小括号表示参数列表 7 // 参数声明方式: java -> 类 ... 
- .editorConfig常用设置
			# http://editorconfig.org root = true [*] # 表示所有文件适用charset = utf-8 # 设置文件字符集为 utf-8indent_style = s ... 
- Vim 速查表 做记录 便于记忆
			Vim 命令速查表 简体中文 • English 简介:Vim 命令速查表,注释化 vimrc 配置文件,经典 Vim 键盘图,实用 Vim 书籍,Markdown 格式,目录化检索,系统化学习,体系 ... 
