HarmonyOS鸿蒙Next之日历组件开发实战(ArkTS)

HarmonyOS鸿蒙Next之日历组件开发实战(ArkTS)

一、组件功能分析

核心功能需求:

  • 支持多行周视图布局(6行×7列)
  • 日期与状态混合展示
  • 不同状态差异化样式:
    • 未填写(红色背景)
    • 已锁定(绿色背景)
  • 跨月日期显示处理
  • 表头星期展示

二、核心实现代码

1. 数据结构定义

// CalendarData.ets
export interface CalendarData {
  date: number
  isCurrentMonth: boolean
  status: 'none' | 'pending' | 'completed'
  hours: number 
}

2. 组件UI实现

@Builder
CalendarHeader() {
  Row() {
    Text(`${this.currentDate.getFullYear()}年${this.currentDate.getMonth() + 1}月`)
      .fontSize(24)
      .fontWeight(FontWeight.Bold)
    Blank()
    Row() {
      Text('今天')
        .border({
          width: 1,
          color: '#ccc',
        })
        .margin({ right: 8 })
        .padding(10)
      Image($r('app.media.ic_prev'))
        .width(24)
        .height(24)
        .margin({ right: 8 })
        .onClick(() => {
          this.currentDate = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() - 1)
          this.generateCalendarData()
        })
      Image($r('app.media.ic_next'))
        .width(24)
        .height(24)
        .onClick(() => {
          this.currentDate = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() + 1)
          this.generateCalendarData()
        })
    }
  }
  .width('100%')
  .padding(16)
}

@Builder
WeekHeader() {
  Row() {
    ForEach(['日', '一', '二', '三', '四', '五', '六'], (day: string) => {
      Text(day)
        .fontSize(14)
        .width('14.28%')
        .textAlign(TextAlign.Center)
    })
  }
  .width('100%')
  .padding({ left: 16, right: 16 })
}

build() {
  Column() {
    this.CalendarHeader()
    this.WeekHeader()
    Grid() {
      ForEach(this.calendarData, (item: CalendarData) => {
        GridItem() {
          Column() {
            Text(`${item.date}`)
              .fontSize(16)
              .fontColor(item.isCurrentMonth ? '#000000' : '#CCCCCC')
            if (item.status !== 'none') {
              Column() {
                Row() {
                  Image(item.status === 'completed' ?
                  $r('app.media.ic_completed') :
                  $r('app.media.ic_pending'))
                    .width(16)
                    .height(16)
                }
                if (item.hours > 0) {
                  Text(`${item.hours}h`)
                    .fontSize(12)
                    .margin({ top: 4 })
                }
              }
              .backgroundColor(item.status === 'completed' ? '#E8F5ED' : '#FFEFED')
              .padding(8)
              .borderRadius(4)
              .width('100%')
            }
          }
          .width('100%')
          .height('100%')
          .padding(8)
          .justifyContent(FlexAlign.SpaceBetween)
        }
      })
    }
    .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')
    .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
    .width('100%')
    .height('100%')
    .padding({ left: 16, right: 16 })
  }
}

3. js交互数据初始化

@State currentDate: Date = new Date()
@State calendarData: CalendarData[] = []

aboutToAppear() {
  this.generateCalendarData()
}
generateCalendarData() {
  const year = this.currentDate.getFullYear()
  const month = this.currentDate.getMonth()

  // 获取当月第一天是星期几
  const firstDay = new Date(year, month, 1).getDay()
  // 获取当月天数
  const daysInMonth = new Date(year, month + 1, 0).getDate()
  // 获取上月天数
  const daysInLastMonth = new Date(year, month, 0).getDate()

  let days: CalendarData[] = []

  // 添加上月末尾几天
  for (let i = firstDay - 1; i >= 0; i--) {
    days.push({
      date: daysInLastMonth - i,
      isCurrentMonth: false,
      status: 'none',
      hours: 0
    })
  }

  // 添加当月天数
  for (let i = 1; i <= daysInMonth; i++) {
    days.push({
      date: i,
      isCurrentMonth: true,
      status: i <= 12 ? (i === 3 || i === 4 ? 'completed' : 'pending') : 'none',
      hours: i < 0 ? 8 : 0
    })
  }

  // 补充下月开始几天
  const remainingDays = 42 - days.length
  for (let i = 1; i <= remainingDays; i++) {
    days.push({
      date: i,
      isCurrentMonth: false,
      status: 'none',
      hours: 0
    })
  }

  this.calendarData = days
}

运行截图: 运行截图

2 回复

在HarmonyOS鸿蒙Next中,日历组件的开发主要依赖于ArkTS语言。ArkTS是一种基于TypeScript的开发语言,专为鸿蒙系统设计,支持声明式UI和状态管理。开发日历组件时,可以使用鸿蒙系统提供的@ohos.calendar模块,该模块提供了日历相关的API,如创建、查询、更新和删除日历事件等。

首先,需要在entry/src/main/ets/pages/Index.ets文件中导入@ohos.calendar模块:

import calendar from '@ohos.calendar';

接下来,可以使用calendar.getCalendarManager()获取日历管理器实例,通过该实例可以进行日历事件的操作。例如,创建一个新的日历事件:

let calendarManager = calendar.getCalendarManager();
let event = {
    title: 'Meeting',
    description: 'Team meeting',
    startTime: new Date().getTime(),
    endTime: new Date().getTime() + 3600000, // 1小时后
    calendarId: 1 // 日历ID
};
calendarManager.addEvent(event).then(() => {
    console.log('Event added successfully');
}).catch((err) => {
    console.error('Failed to add event:', err);
});

要查询日历事件,可以使用calendarManager.queryEvents()方法:

let options = {
    startTime: new Date().getTime(),
    endTime: new Date().getTime() + 86400000 // 查询未来24小时的事件
};
calendarManager.queryEvents(options).then((events) => {
    console.log('Events:', events);
}).catch((err) => {
    console.error('Failed to query events:', err);
});

更新和删除日历事件分别使用calendarManager.updateEvent()calendarManager.deleteEvent()方法。

在UI部分,可以使用ArkUI组件来展示日历事件。例如,使用List组件展示查询到的事件列表:

@Entry
@Component
struct CalendarPage {
    @State events: Array<calendar.CalendarEvent> = [];

    build() {
        List({ space: 10 }) {
            ForEach(this.events, (event) => {
                ListItem() {
                    Text(event.title).fontSize(20)
                    Text(event.description).fontSize(14)
                }
            })
        }
    }
}

通过以上步骤,可以在HarmonyOS鸿蒙Next中实现一个基本的日历组件,支持事件的增删改查和展示。

更多关于HarmonyOS鸿蒙Next之日历组件开发实战(ArkTS)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,使用ArkTS开发日历组件可通过以下步骤实现:

  1. 创建项目:在DevEco Studio中新建ArkTS项目。
  2. 引入组件库:使用@ohos.calendar模块访问日历功能。
  3. 定义UI:使用ArkUI框架构建日历界面,如Flex布局和Text组件。
  4. 数据处理:通过CalendarManager获取和操作日历数据,如事件、提醒等。
  5. 交互逻辑:实现用户交互,如日期选择和事件添加。

示例代码:

import calendar from '@ohos.calendar';

// 获取日历实例
let calendarManager = calendar.getCalendarManager();

// 查询日历事件
calendarManager.getEvents((err, events) => {
  if (err) {
    console.error('Failed to get events:', err);
    return;
  }
  console.log('Events:', events);
});

通过以上步骤,您可以快速开发出功能丰富的日历组件。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!