• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 *
3 * Copyright (c) 2025 Huawei Device Co., Ltd.
4 *
5 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 *
9 * Redistributions of source code must retain the above copyright notice,this
10 * list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS,
23 *
24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26import hilog from '@ohos.hilog'
27import { getMonthDate } from './GetDate';
28import { Month, MonthDataSource } from './MonthDataSource';
29import {
30  memo,
31  __memo_context_type,
32  __memo_id_type
33} from '@ohos.arkui.stateManagement' // should be insert by ui-plugins
34import {
35  Text,
36  TextAttribute,
37  Column,
38  Component,
39  Button,
40  ButtonAttribute,
41  ClickEvent,
42  UserView,
43  Flex,
44  ItemAlign,
45  ForEach,
46  FlexWrap,
47  Entry,
48  TextAlign,
49  $r,
50  Color,
51  HorizontalAlign,
52  SafeAreaType,
53  Row,
54  LazyForEach,
55  SafeAreaEdge,
56  Span,
57  List,
58  EdgeEffect,
59  BarState,
60  Scroll,
61  Scroller,
62  ExpectedFrameRateRange,
63  ListItem
64} from '@ohos.arkui.component'; // TextAttribute should be insert by ui-plugins
65import {
66  State,
67  Link,
68  StateDecoratedVariable,
69  MutableState,
70  stateOf,
71  observableProxy
72} from '@ohos.arkui.stateManagement'; // should be insert by ui-plugins
73import { Context, UIContext } from '@ohos.arkui.UIContext';
74
75const MONDAY = '一';
76const TUESDAY = '二';
77const WEDNESDAY = '三';
78const THURSDAY = '四';
79const FRIDAY = '五';
80const SATURDAY = '六';
81const SUNDAY = '日';
82const WEEK: string[] = [SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY]; // 设置日历周,从周日开始
83const MONTH: string = '月';
84const YEAR: string = '年';
85
86/**
87 * 通过组件复用,加载每个月份的数据,当数据量较多时,快速滑动到底部,会出现掉帧的情况。
88 */
89
90@Component
91export struct ReusePage {
92  @State contentData: MonthDataSource = new MonthDataSource(); // 列表数据
93  nowDate: Date = new Date();
94  currentMonth: number = this.nowDate.getMonth() + 1; // 当前月份
95  currentDay: number = this.nowDate.getDate(); // 当前日
96  currentYear: number = this.nowDate.getFullYear(); // 当前年份
97  currentWeekDay: number = new Date(this.currentYear, this.currentMonth - 1, this.currentDay).getDay(); // 当前周几
98  private scroller: Scroller = new Scroller(); // 二级列表Scroller对象
99
100  // 初始化日历中一年的数据
101  initCalenderData() {
102    for (let k = this.currentYear; k < 2035; ++k) {
103      for (let i = 1; i <= 12; i++) {
104        // 获取每个月的日数据
105        const monthDays: number[] = getMonthDate(i, k);
106        const month: Month = {
107          month: i + MONTH,
108          num: i,
109          days: monthDays,
110          year: k
111        };
112        this.contentData.pushData(month);
113      }
114    }
115  }
116
117  aboutToAppear() {
118    this.initCalenderData();
119  }
120
121  build() {
122    Column() {
123      Text(this.currentYear + YEAR)
124        .width('100%')
125        .height(40)
126        .fontSize(20)
127        .fontColor(Color.Black)
128        .backgroundColor($r('app.color.highlyloadedcomponentrender_color_year_background'))
129        .textAlign(TextAlign.Center)
130        .id('id_highly_loaded_component_render_title')
131      List() {
132        LazyForEach(this.contentData, (monthItem: Month) => {
133          ListItem() {
134            ItemView({
135              monthItem: monthItem,
136              currentMonth: this.currentMonth,
137              currentDay: this.currentDay,
138              currentYear: this.currentYear
139            })
140          }.width('100%')
141        })
142      }
143      .width('100%')
144    }
145    .width('100%')
146    .height('100%')
147    .backgroundColor($r('app.color.ohos_id_color_background'))
148    .alignItems(HorizontalAlign.Center)
149    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
150  }
151}
152
153// @Reusable
154@Component
155struct ItemView {
156  @State monthItem: Month = {
157    month: '',
158    num: 0,
159    days: [],
160    year: 0
161  } as Month;
162  private currentMonth: number = 0;
163  private currentYear: number = 0; // 当前年份
164  private currentDay: number = 0;
165  private temp: Month[] = new Array<Month>();
166  private step: number = 0;
167  private maxStep: number = 2; // 最多执行的帧数
168  readonly MAX_EVERY_FRAME: number = 5; // 每帧最多处理的数据量
169  @State month: string = '';
170  @State monthNumber: number = 0;
171  @State days: number[] = new Array<number>();
172  @State year: number = 0;
173
174  build() {
175    Flex({ wrap: FlexWrap.Wrap }) {
176      // 月份信息
177      Text(this.monthItem.month)
178        .fontSize(25)
179        .height(40)
180        .fontColor(Color.Black)
181        .width('100%')
182        .textAlign(TextAlign.Start)
183        .layoutWeight(1)
184
185      ForEach(WEEK, (weekday: string) => {
186        Text(weekday)
187          .fontSize(20)
188          .width(50)
189          .height(30)
190          .fontColor(weekday === SUNDAY || weekday === SATURDAY ? Color.Red : Color.Black)
191          .borderRadius(10)
192          .textAlign(TextAlign.Center)
193          .layoutWeight(1)
194      })
195      // 日期信息
196      ForEach(this.monthItem.days, (day: number, index: number) => {
197        Text() {
198          Span(JSON.stringify(day))
199            .fontSize(20)
200        }
201        .height(50)
202        .width(50)
203        .opacity(day === 0 ? 0 : 1)
204        .fontColor(Color.Black)
205        .borderRadius(10)
206        .textAlign(TextAlign.Center)
207        .backgroundColor(day === this.currentDay && this.monthItem.num === this.currentMonth &&
208          this.monthItem.year === this.currentYear ?
209        $r('app.color.ohos_id_color_palette9') : Color.Transparent)
210        .layoutWeight(1)
211      })
212    }
213    .alignSelf(ItemAlign.Start)
214    .backgroundColor(Color.Transparent)
215    .width(350)
216  }
217}