diff --git a/OAT.xml b/OAT.xml index 8b1ee7c6171ed83c2ce05e6858416eb902b9b986..22b92b5dc0e0269de8f2eb032ae6e4db0401f570 100644 --- a/OAT.xml +++ b/OAT.xml @@ -171,6 +171,15 @@ Note:If the text contains special characters, please escape them according to th + + + + + + + + + @@ -2150,6 +2159,11 @@ Note:If the text contains special characters, please escape them according to th + + + + + @@ -2235,6 +2249,11 @@ Note:If the text contains special characters, please escape them according to th + + + + + diff --git a/code/ArkTS1.2/ComponentSample/.gitignore b/code/ArkTS1.2/ComponentSample/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/AppScope/app.json5 b/code/ArkTS1.2/ComponentSample/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4459be73fa80092f61b55a4bfdf16e630f933bbd --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/AppScope/app.json5 @@ -0,0 +1,36 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +{ + "app": { + "bundleName": "com.samples.componentSampleTest", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/code/ArkTS1.2/ComponentSample/AppScope/resources/base/element/string.json b/code/ArkTS1.2/ComponentSample/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..2b122b5a83fa120fe673cea575d07613d85c2518 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "componentSampleTest" + } + ] +} diff --git a/code/ArkTS1.2/ComponentSample/AppScope/resources/base/media/app_icon.png b/code/ArkTS1.2/ComponentSample/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3 Binary files /dev/null and b/code/ArkTS1.2/ComponentSample/AppScope/resources/base/media/app_icon.png differ diff --git a/code/ArkTS1.2/ComponentSample/README.md b/code/ArkTS1.2/ComponentSample/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ba7b57f0ec2d9088507cf61745faf15c337b222b --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/README.md @@ -0,0 +1,102 @@ +# 组件复用示例 + +### 介绍 + +1.主页实现图文混排组件复用场景; +2.实现日历场景的组件复用,属于高负载刷新的组件复用场景; + +### 效果预览 + +效果如下所示: + +|主界面|列表二级联动|自定义日历选择器|跨文件样式复用和组件复用|合理处理高负载组件的渲染文章示例代码| +|--------------------------------|--------------------------------|--------------------------------|--------------------------------|--------------------------------| +|![Alt text](entry/src/main/resources/base/media/main.PNG)|![Alt text](entry/src/main/resources/base/media/example1.PNG)|![Alt text](entry/src/main/resources/base/media/example2.PNG)|![Alt text](entry/src/main/resources/base/media/example3.PNG)|![Alt text](entry/src/main/resources/base/media/example4.PNG)| + +使用说明 + +1. 在主界面,点击蓝色按钮"列表二级联动"。 + * 滑动二级列表侧控件,一级列表随之滚动。 + * 点击一级列表,二级列表随之滚动。 +2. 在主界面,点击蓝色按钮"自定义日历选择器"。 + * 点击购物车页面的list列表跳转商品详情页。 +3. 在主界面,点击蓝色按钮"跨文件样式复用和组件复用"。 + * 加载完成后显示主界面,点当前日期后会显示日历选择器,选择日期后会关闭日历选择器,主页面日期会变成选定的日期。 +4. 在主界面,点击蓝色按钮"合理处理高负载组件的渲染文章示例代码"。 + * 加载10年的日历数据。 + + +### 工程目录 + +``` +entry/src/main/ets/ +|---pages +| |---Example1 +| | |---DataType.ets // 数据类型定义 +| | |---Example1.ets +| | |---SecondaryLinkExample.ets // 二级联动功能实现页面 +| |---Example2 +| | |---components +| | | |---DateModel.ets // 数据类型定义 +| | | |---GetDate.ets // 获取日期信息 +| | | |---MonthDataSource.ets // 数据类型定义 +| | |----view +| | | |---CalendarView.ets // 场景主页面 + 自定义日历 +| | |---Example2.ets +| |---Example3 +| | |---components +| | | |---CommonText.ets // 自定义组件封装 +| | | |---LazyForEach.ets // 懒加载 +| | |----view +| | | |---Details.ets // 页面:详情页 +| | | |---ShoppingCart.ets // 页面:购物车 +| | |---Example3.ets +| |---Example4 +| | |---GetDate.ets // 获取日期信息 +| | |---MonthDataSource.ets // 懒加载数据类型 +| | |---Example4.ets +| | |---ReusePage.ets // 正常加载数据的页面 +| |---index.ets // 首页 +``` + +### 具体实现 + +* Example1(列表二级联动) 源码参考: [Example1](entry/src/main/ets/pages/Example1) + * 构造懒加载数据源类型[MyDataSource](entry/src/main/ets/pages/Example1/DataType.ets) + * 一二级列表分别绑定不同的Scroller对象,一级列表(tagLists)绑定classifyScroller对象,二级列表绑定scroller对象。 + * 通过循环,构造一二级列表数据。 + * 点击一级列表后,通过一级列表的索引获取二级列表的索引,调用scrollToIndex方法将一二级列表滚动到指定索引值。 + * 滑动二级列表触发组件滚动事件后,获取到列表可视区域第一个item对应的索引值,通过二级列表索引获取一级列表索引,调用scrollToIndex方法将一级列表滚动到指定索引值。 +* Example2(自定义日历选择器) 源码参考: [Example2](entry/src/main/ets/pages/Example2) + * 获取当前月和下个月的日期信息。源码参考[GetDate.ets](entry/src/main/ets/pages/Example2/components/GetDate.ets) + * 通过Flex类初始化自定义日历界面。源码参考[CalendarView.ets](entry/src/main/ets/pages/Example2/view/CalendarView.ets)。 +* Example3(跨文件样式复用和组件复用) 源码参考: [Example3](entry/src/main/ets/pages/Example3) + * 使用了自定义封装的Image+Text的图文复合组件[ImageText](entry/src/main/ets/pages/Example3/common/CommonText.ets) +* Example4(合理处理高负载组件的渲染文章示例代码) 源码参考: [Example4](entry/src/main/ets/pages/Example4) + * 通过组件复用,加载10年的日历数据。源码参考:[ReusePage.ets](entry/src/main/ets/pages/Example4/ReusePage.ets) + +### 相关权限 + +无 + +### 依赖 + +无 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:Phone; +2. 本示例为Stage模型,支持API20版本SDK,SDK版本号(API Version 20),镜像版本号(5.0.0.5)。 +3. 本示例需要使用DevEco Studio 版本号(6.0.0.6)版本才可编译运行。 + +### 下载 + +如需单独下载本工程,执行如下命令: + +``` +git init +git config core.sparsecheckout true +echo code/ArkTS1.2/ComponentSample/ > .git/info/sparse-checkout +git remote add origin https://gitee.com/openharmony/applications_app_samples.git +git pull +``` \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/build-profile.json5 b/code/ArkTS1.2/ComponentSample/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c83260a8d4a7c41693901753e0c0ea562824569c --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/build-profile.json5 @@ -0,0 +1,68 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "arkTSVersion": "1.2", + "compatibleSdkVersion": "6.0.0(20)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/code-linter.json5 b/code/ArkTS1.2/ComponentSample/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..87b3919d419c09728067f1b545b7e2d5116adc07 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/code-linter.json5 @@ -0,0 +1,58 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/.gitignore b/code/ArkTS1.2/ComponentSample/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/build-profile.json5 b/code/ArkTS1.2/ComponentSample/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..36f9e65afb2abbbbdda625e86543807eee16240c --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/build-profile.json5 @@ -0,0 +1,54 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/hvigorfile.ts b/code/ArkTS1.2/ComponentSample/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..8f830cdfd5bfdd8bde92ebfc27fc0562423dca3d --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/hvigorfile.ts @@ -0,0 +1,32 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/code/ArkTS1.2/ComponentSample/entry/obfuscation-rules.txt b/code/ArkTS1.2/ComponentSample/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/oh-package.json5 b/code/ArkTS1.2/ComponentSample/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..39ab3f901494a87d5ab258dfaa9e6882de1f5166 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/oh-package.json5 @@ -0,0 +1,36 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/entryability/EntryAbility.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..7cfa74313136d60906a788b73684b8d3539b7120 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,56 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import Want from '@ohos.app.ability.Want'; +import window from '@ohos.window'; +import { BusinessError } from '@ohos.base'; +import hilog from '@ohos.hilog'; +import {globalContext} from './GlobalContext'; + +class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', 'EntryAbility onCreate'); + globalContext.setAbilityContext(this.context); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + hilog.info(0x0000, 'testTag', 'EntryAbility onWindowStageCreate'); + try { + windowStage.loadContent('pages/Index', (err: BusinessError): void => { + hilog.info(0x0000, 'testTag', 'loadContent entering'); + if (err.code) { + hilog.error(0x0000, 'testTag', 'loadContent error'); + return; + } + hilog.info(0x0000, 'testTag', 'loadContent ok'); + }); + } catch (e: Error) { + hilog.error(0x0000, 'testTag', 'loadContent catch error:-----------' + e.message); + } + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/entryability/GlobalContext.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/entryability/GlobalContext.ets new file mode 100644 index 0000000000000000000000000000000000000000..e63a822c2f8aa9b43da8394a626367dcc5d94b93 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/entryability/GlobalContext.ets @@ -0,0 +1,44 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import common from '@ohos.app.ability.common'; + +export class GlobalContext { + private abilityContext: common.UIAbilityContext | null = null; + + setAbilityContext(context: common.UIAbilityContext): void { + this.abilityContext = context; + } + + getAbilityContext(): common.UIAbilityContext { + if (!this.abilityContext) { + throw new Error('AbilityContext'); + } + return this.abilityContext!; + } +} + +export const globalContext = new GlobalContext(); \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example1/DataType.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example1/DataType.ets new file mode 100644 index 0000000000000000000000000000000000000000..82d7e7734e035c4742c29cbc1490b2cfba44cb7b --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example1/DataType.ets @@ -0,0 +1,206 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { memo, __memo_context_type, __memo_id_type } from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import {IDataSource,DataChangeListener,Text, TextAttribute, Column, Component, Button, ButtonAttribute, ClickEvent, UserView ,Image,Row} from "@ohos.arkui.component"; // TextAttribute should be insert by ui-plugins +import { State, StateDecoratedVariable, MutableState, stateOf, observableProxy ,Provide} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +const CONTENT_PER_TAG = 10; // 每个TAG对应多少个元素 +/** + * 代表自定义类型数据的接口。 + * + * @interface + * @property {string} desc - 描述。 + * @property {string} tag - 类别。 + */ +export interface CustomDataType { + desc: string, + tag: string, +} + +/** + * 一级列表可视区域的起始索引和终点索引。 + * + * @interface + * @property {number} start - 可视区域起点索引。 + * @property {number} end - 可视区域终点索引。 + */ +export interface ListIndexPosition { + start: number, + end: number +} + +/** + * Basic implementation of IDataSource to handle data listener + * + * @class + * @implements {IDataSource} + */ +class BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = Array(); + private originDataArray: CustomDataType[] = Array(); + + /** + * 获取数组长度。 + * @returns {number} 返回数组长度。 + */ + public totalCount(): double { + return 0; + } + + /** + * 获取指定索引数据。 + * @param {number} index - 索引值。 + * @returns {CustomDataType} 返回指定索引数据。 + */ + public getData(index: double): CustomDataType { + return this.originDataArray[index]; + } + + /** + * 为LazyForEach组件向其数据源处添加listener监听。 + * @param {DataChangeListener} listener - 监听对象。 + */ + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + console.info('add listener'); + this.listeners.push(listener); + } + } + + /** + * 为对应的LazyForEach组件在数据源处去除listener监听。 + * @param {DataChangeListener} listener - 监听对象。 + */ + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + console.info('remove listener'); + this.listeners.splice(pos, 1); + } + } + + /** + * 通知LazyForEach组件需要在index对应索引处添加子组件。 + * @param {number} index - 索引值。 + */ + notifyDataAdd(index: double): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + /** + * 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件。 + * @param {number} index - 索引值。 + */ + notifyDataChange(index: double): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + /** + * 通知LazyForEach组件需要在index对应索引处删除该子组件 + * @param {number} index - 索引值。 + */ + notifyDataDelete(index: double): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + /** + * 通知LazyForEach组件将from索引和to索引处的子组件进行交换 + * @param {number} from - 起始值。 + * @param {number} to - 终点值。 + */ + notifyDataMove(from: double, to: double): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } +} + +/** + * 继承自BasicDataSource的子类,重写了方法。 + * + * @class + * @extends {BasicDataSource} + */ +export class MyDataSource extends BasicDataSource { + public dataArray: CustomDataType[] = Array(); + + /** + * 获取数组长度。 + * @returns {number} 返回数组长度。 + */ + public totalCount(): double { + return this.dataArray.length; + } + + /** + * 获取指定索引数据。 + * @param {number} index - 索引值。 + * @returns {CustomDataType} 返回指定索引数据。 + */ + public getData(index: double): CustomDataType { + return this.dataArray[index]; + } + + /** + * 改变单个数据。 + * @param {number} index - 索引值。 + * @param {CustomDataType} data - 修改后的值。 + */ + public addData(index: double, data: CustomDataType): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + /** + * 添加数据。 + * @param {CustomDataType} data - 需要添加的数据。 + */ + public pushData(data: CustomDataType[]): void { + if (Array.isArray(data)) { + for (let i = 0; i < CONTENT_PER_TAG; ++i) { + this.dataArray.push(data[i]); + } + } + this.notifyDataAdd(this.dataArray.length - 1); + } +} + +// 常量数据 +export enum COMPONENT_STYLE { + ITEM_GUTTER = 12, + TAG_TEXT_HEIGHT= 75, + SUB_ITEM_GUTTER= 7, + SUB_ITEM_HEIGHT= 96, + SUB_ITEM_TEXT_WIDTH_TITLE= 56, + SUB_ITEM_TEXT_HEIGHT= 12, + SUB_ITEM_TEXT_WIDTH_BODY= 120, + BOTTOM_TOAST_TEXT_MAX_HEIGHT= 200 +}; \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example1/Example1.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example1/Example1.ets new file mode 100644 index 0000000000000000000000000000000000000000..1613fbcac33ad962468204a26d2cb6843ea5ba30 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example1/Example1.ets @@ -0,0 +1,83 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { + memo, + __memo_context_type, + __memo_id_type +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import { + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + Row, + TextAlign, + Entry +} from "@ohos.arkui.component"; // TextAttribute should be insert by ui-plugins +import { + State, + Link, + StateDecoratedVariable, + MutableState, + stateOf, + observableProxy +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import hilog from '@ohos.hilog' +import { Context,UIContext} from '@ohos.arkui.UIContext' +import { SecondaryLinkExample } from './SecondaryLinkExample'; +@Entry +@Component +struct Example1Test { + aboutToAppear() { + + } + build() { + Column() { + Row() { + Text("← 返回").fontSize(20) + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().back(); + }).width("100%") + }.height("5%") + SecondaryLinkExample() + } + } +} + +export class ComExampleTrivialApplication extends UserView { + getBuilder() { + hilog.info(0x0000, 'testTag', 'getBuilder'); + let wrapper = @memo() =>{ + hilog.info(0x0000, 'testTag', 'Example1Test'); + Example1Test(undefined); + } + return wrapper; + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example1/SecondaryLinkExample.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example1/SecondaryLinkExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..44d485458127137166afbb5d9b731d42437c137e --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example1/SecondaryLinkExample.ets @@ -0,0 +1,307 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { CustomDataType, MyDataSource, ListIndexPosition, COMPONENT_STYLE } from './DataType'; +import { + memo, + __memo_context_type, + __memo_id_type +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import { + WordBreak, + TextOverflow, + TouchType, + TextAlign, + FontWeight, + FlexAlign, + HorizontalAlign, + BarState, + Scroller, + Scroll, + SafeAreaType, + SafeAreaEdge, + ListItem, + Axis, + LazyForEach, + List, + TouchEvent, + ForEach, + Flex, + FlexWrap, + Builder, + NavDestination, + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + Image, + Row, + CalendarPickerDialog,$r +} from "@ohos.arkui.component"; // TextAttribute should be insert by ui-plugins +import { + State, + StateDecoratedVariable, + MutableState, + stateOf, + observableProxy, + Watch +} from "@ohos.arkui.stateManagement";// should be insert by ui-plugins +import hilog from '@ohos.hilog'; + +const TAG_LIST_LENGTH = 12; // TagList长度 +const CONTENT_PER_TAG = 10; // 每个TAG对应多少个元素 + +/** + * 功能描述: 本示例主要介绍了List组件实现二级联动(Cascading List)的场景 + * + * 推荐场景: 需要使用多级列表联合滚动的场景,如:外卖点单页面等 + * + * 核心组件: + * 1. SecondaryLinkExample.tagListItemBuilder + * + * 实现步骤: + * 1. 一二级列表分别绑定不同的Scroller对象,一级列表(tagLists)绑定classifyScroller对象,二级列表绑定scroller对象 + * 2. 点击一级列表后,通过一级列表的索引获取二级列表的索引,调用scrollToIndex方法将一二级列表滚动到指定索引值 + * 3. 滑动二级列表触发组件滚动事件后,获取到列表可视区域第一个item对应的索引值,通过二级列表索引获取一级列表索引,调用scrollToIndex方法将一级列表滚动到指定索引值 + */ +@Component +export struct SecondaryLinkExample { + private tagIndexPosition: ListIndexPosition = { start: 0, end: 0 } as ListIndexPosition; // 一级列表可视区域的起始索引和终点索引 初始化失败 + @State @Watch('onIndexChange') currentTagIndex: number = 0; // 一级列表焦点索引值 + private tagLists: Array = new Array(); // 一级列表数据 + @State contentData: MyDataSource = new MyDataSource(); // 二级列表数据 + private records: Array = new Array(); // 二级列表分组count数量 + // TODO:知识点: 1.级联列表分别绑定不同的Scroller对象,通过调用Scroller对象方法实现控制列表滚动 + private classifyScroller: Scroller = new Scroller(); // 一级列表Scroller对象 + private scroller: Scroller = new Scroller(); // 二级列表Scroller对象 + private isClickTagList: boolean = false; // 是否点击一级列表 + + /** + * 生命周期函数 + */ + aboutToAppear(): void { + // 构造数据 + for (let i = 0; i < TAG_LIST_LENGTH; i++) { + this.tagLists.push(`类别${i + 1}`); + const tempData: Array = new Array(CONTENT_PER_TAG).fill({ + desc: '内容数据', + tag: `类别${i + 1}` + }); + this.records.push(i * CONTENT_PER_TAG); + this.contentData.pushData(tempData); + } + this.records.push(CONTENT_PER_TAG * TAG_LIST_LENGTH); + this.tagIndexPosition = { start: 0, end: 0 }; + } + + build() { + Column() { + Column() { + Text($r('app.string.secondarylinkage_secondary_link')) + .fontSize(20) + Text($r('app.string.secondarylinkage_secondary_link_desc')) + .fontSize(20) + .wordBreak(WordBreak.BREAK_ALL) + } + .width('100%') + .backgroundColor("#ffcac6c6") + .borderRadius(12) + .padding(12) + + Row() { + // TODO:知识点: 2.一级列表绑定Scroller对象 + List({ scroller: this.classifyScroller, initialIndex: 0 }) { + ForEach(this.tagLists, (item: string, index: number) => { + this.tagListItemBuilder(item, index); + }, (item: string, index: number) => item) + } + .backgroundColor("#ffe3e3e3") + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .onScrollIndex((start: number, end: number): void => { + this.tagIndexPosition = { start, end }; + }) + .listDirection(Axis.Vertical) + .scrollBar(BarState.Off) + .height('100%') + .width('30%') + // 二级列表 + List({ scroller: this.scroller}) { + ForEach(this.contentData.dataArray, (item: CustomDataType, index: number) => { + this.contentListItemBuilder(item, index); + }) + this.contentListNoMoreBuilder(); + } + .backgroundColor("#ffffffff") + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .id('list_content') + .scrollBar(BarState.Off) + .listDirection(Axis.Vertical) // 列表排列方向水平 + .flexShrink(1) + .onTouch((event: TouchEvent): void => { + if (event.type === TouchType.Down) { + this.isClickTagList = false; // 当前点击的非一级列表 + } + }) + // 性能知识点:onScrollIndex事件在列表滚动时频繁执行,在回调中需要尽量减少耗时和冗余操作,例如减少不必要的日志打印 + .onScrollIndex((start: number): void => { + // TODO:知识点: 4.滑动二级列表触发组件滚动事件后,返回列表可视区域的第一个item对应的索引值,当前通过二级列表索引获取一级列表索引,操作一级列表Scroller对象使列表滚动到指定位置 + const currentClassIndex = this.findClassIndex(start); + if (currentClassIndex !== this.currentTagIndex && this.isClickTagList !== true) { + this.currentTagIndex = currentClassIndex; + this.classifyScroller.scrollToIndex(currentClassIndex, true); + } + }) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .width('100%') + .layoutWeight(1) + } + } + + /** + * 内容底部"没有更多"视图 + */ + @Builder + contentListNoMoreBuilder() { + ListItem() { + Text($r('app.string.secondarylinkage_nomore')) + .fontSize(20) + .backgroundColor("#ffb8b8b8") + } + .width('100%') + } + + /** + * 右侧内容视图 + */ + @Builder + contentListItemBuilder(item: CustomDataType, index: number) { + ListItem() { + Row() { + Text() + .aspectRatio(1) + .height('100%') + .backgroundColor("#ffe5e5e5") + .borderRadius(15) + Column() { + Text(item.desc + index) + Text(item.tag) + .fontSize(20) + .fontColor("#ff1dee06") + Text() + .height(COMPONENT_STYLE.SUB_ITEM_TEXT_HEIGHT) + .width(COMPONENT_STYLE.SUB_ITEM_TEXT_WIDTH_TITLE) + .backgroundColor("#ffb8b8b8") + Text() + .height(COMPONENT_STYLE.SUB_ITEM_TEXT_HEIGHT) + .width(COMPONENT_STYLE.SUB_ITEM_TEXT_WIDTH_BODY) + .backgroundColor("#ff8f8f8f") + } + .width('100%') + .alignItems(HorizontalAlign.Start) + .justifyContent(FlexAlign.SpaceEvenly) + .height('100%') + } + .backgroundColor("#ffffffff") + .height(COMPONENT_STYLE.SUB_ITEM_HEIGHT) + } + .id('content_' + index) + } + + /** + * 左侧类别视图 + */ + @Builder + tagListItemBuilder(item: string, index: number) { + ListItem() { + Text(item) + .width('100%') + .height(COMPONENT_STYLE.TAG_TEXT_HEIGHT) + .textAlign(TextAlign.Center) + .onTouch((event: TouchEvent) => { + if (event.type === TouchType.Down) { + this.isClickTagList = true; // 当前点击的是一级列表 + } + }) + .onClick((e: ClickEvent): void => { + // TODO:知识点: 3.点击一级列表后,通过一级列表索引获取二级列表索引,分别操作不同的Scroller对象使列表滚动到指定位置 + this.currentTagIndex = index; + const itemIndex = this.findItemIndex(index); + this.scroller.scrollToIndex(itemIndex, true); + }) + .backgroundColor(this.currentTagIndex === index ? "#ffffffff" : '#ffe3e3e3') + } + .id(this.currentTagIndex === index ? 'type_' + index : 'type_' + index + '_selected') + } + + /** + * 根据一级列表索引值获取二级列表索引值 + * + * @param {number} index - 一级列表索引值 + * @returns {number} 二级列表索引值 + */ + findItemIndex(index: number): number { + return this.records[index]; + } + + /** + * 根据二级列表索引值获取对应一级列表索引 + * + * @param {number} index - 二级列表索引值 + * @returns {number} 一级列表索引值 + */ + findClassIndex(index: number): number { + let ans = 0; + for (let i = 0; i < this.records.length; i++) { + if (index >= this.records[i] && index < this.records[i + 1]) { + ans = i; + break; + } + } + return ans; + } + + /** + * 监听一级列表获焦索引变化 + */ + onIndexChange(s: string) { + const start = this.tagIndexPosition.start; + const end = this.tagIndexPosition.end; + if ((this.currentTagIndex === end || this.currentTagIndex === end - 1)) { + let leftScrollCount: number = this.currentTagIndex + 1; + leftScrollCount = leftScrollCount >= this.tagLists.length - 1 ? this.tagLists.length - 1 : leftScrollCount; + this.classifyScroller.scrollToIndex(leftScrollCount, true); // 使获焦item向左滚动 + } + if (this.currentTagIndex === start || this.currentTagIndex === start + 1) { + let rightScrollCount: number = this.currentTagIndex - 1; + rightScrollCount = rightScrollCount <= 0 ? 0 : rightScrollCount; + this.classifyScroller.scrollToIndex(rightScrollCount, true); // 使获焦item向右滚动 + } + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/Example2.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/Example2.ets new file mode 100644 index 0000000000000000000000000000000000000000..9f0184c0775d198eea409deff70388d223856826 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/Example2.ets @@ -0,0 +1,82 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { + memo, + __memo_context_type, + __memo_id_type +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import { + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + Row, + Entry +} from "@ohos.arkui.component"; // TextAttribute should be insert by ui-plugins +import { + State, + Link, + StateDecoratedVariable, + MutableState, + stateOf, + observableProxy +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import hilog from '@ohos.hilog'; +import { Context,UIContext} from '@ohos.arkui.UIContext'; +import { CalendarView } from "./view/CalendarView"; +@Entry +@Component +struct Example2Test { + aboutToAppear() { + } + + build() { + Column() { + Row() { + Text("← 返回").fontSize(20) + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().back() + }).width("100%") + }.height("5%") + CalendarView(); + } + } +} + +export class ComExampleTrivialApplication extends UserView { + getBuilder() { + hilog.info(0x0000, 'testTag', 'getBuilder'); + let wrapper = @memo() =>{ + hilog.info(0x0000, 'testTag', 'Example2Test'); + Example2Test(undefined); + } + return wrapper; + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/components/DateModel.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/components/DateModel.ets new file mode 100644 index 0000000000000000000000000000000000000000..d7be0116e5e63b893ac5f80779d0dd162d502485 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/components/DateModel.ets @@ -0,0 +1,41 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * 设置项的数据类 + */ +export class DateModel { + day: number; + week: number; + month: number; + year: number; + + constructor(day: number, week: number, month: number, year: number) { + this.day = day; + this.week = week; + this.month = month; + this.year = year; + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/components/GetDate.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/components/GetDate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e04e442193f4518010f0b9ccf51df64b78e9a17d --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/components/GetDate.ets @@ -0,0 +1,72 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { DateModel } from './DateModel'; + +const SATURDAY = 6; // 日历表上周六对应的序列号,从周日开始算起,取值0~6 + +/* + * 根据指定年份和月份获取该月在日历表上的日期排布数据 + * @param { number } specifiedMonth - 指定月份 + * @param { number } specifiedYear - 指定年份 + */ +export function getMonthDate(specifiedMonth: number, specifiedYear: number): 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.push(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; +} + +/* + * 获取当前日期,年月日星期几 + */ +export function getRealTimeDate(): DateModel { + const nowDate = new Date(); // 创建Date对象,设置当前日期和时间 + let currentMonth = nowDate.getMonth() + 1; // 获取当前月份,getMonth()获得的值是0~11,实际月份需要+1 + let currentDay = nowDate.getDate(); // 获取当前日 + let currentYear = nowDate.getFullYear(); // 获取当前年份 + let currentWeekDay = new Date(currentYear, currentMonth - 1, currentDay).getDay(); // 获取当前星期几 + let nowDateModel = new DateModel(0, 0, 0, 0); // 创建DateModel实例 + nowDateModel.day = currentDay; + nowDateModel.week = currentWeekDay; + nowDateModel.month = currentMonth; + nowDateModel.year = currentYear; + return nowDateModel; +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/components/MonthDataSource.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/components/MonthDataSource.ets new file mode 100644 index 0000000000000000000000000000000000000000..905719e28d80254ffb867c74f41e8f6a35b77917 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/components/MonthDataSource.ets @@ -0,0 +1,150 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { + IDataSource, + DataChangeListener, + Component, + UserView, + Builder,Resource,$r,Row +} from "@ohos.arkui.component"; // TextAttribute should be insert by ui-plugins +import { State, Link, StorageLink, Watch } from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins + +export interface Month { + month: string; // 具体年月 + num: number; // 月份 + days: number[]; // 该月日期 +} + +/** + * Basic implementation of IDataSource to handle data listener + * + * @class + * @implements {IDataSource} + */ +export class MonthDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + public dataArray: Month[] = new Array(); + + /** + * 获取数组长度。 + * @returns {number} 返回数组长度。 + */ + public totalCount(): number { + return this.dataArray.length; + } + + /** + * 获取指定索引数据。 + * @param {number} index - 索引值。 + * @returns {CustomDataType} 返回指定索引数据。 + */ + public getData(index: number): Month { + return this.dataArray[index]; + } + + /** + * 为LazyForEach组件向其数据源处添加listener监听。 + * @param {DataChangeListener} listener - 监听对象。 + */ + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + console.info('add listener'); + this.listeners.push(listener); + } + } + + /** + * 为对应的LazyForEach组件在数据源处去除listener监听。 + * @param {DataChangeListener} listener - 监听对象。 + */ + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + console.info('remove listener'); + this.listeners.splice(pos, 1); + } + } + + /** + * 通知LazyForEach组件需要在index对应索引处添加子组件。 + * @param {number} index - 索引值。 + */ + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + /** + * 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件。 + * @param {number} index - 索引值。 + */ + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + /** + * 通知LazyForEach组件需要在index对应索引处删除该子组件 + * @param {number} index - 索引值。 + */ + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + /** + * 通知LazyForEach组件将from索引和to索引处的子组件进行交换 + * @param {number} from - 起始值。 + * @param {number} to - 终点值。 + */ + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } + + /** + * 改变单个数据。 + * @param {number} index - 索引值。 + * @param {CustomDataType} data - 修改后的值。 + */ + public addData(index: number, data: Month): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + /** + * 添加数据。 + * @param {CustomDataType} data - 需要添加的数据。 + */ + public pushData(data: Month): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/view/CalendarView.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/view/CalendarView.ets new file mode 100644 index 0000000000000000000000000000000000000000..766bb16eb538e853bd539febec9d464017444d7f --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example2/view/CalendarView.ets @@ -0,0 +1,283 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { DateModel } from '../components/DateModel'; +import { getRealTimeDate, getMonthDate } from '../components/GetDate'; +import promptAction from '@ohos.promptAction'; +import { + memo, + __memo_context_type, + __memo_id_type +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import { + Text, + TextAttribute, + Column, + FlexAlign, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + List, + ListItem, + Image, + Tabs, + TabContent, + Row, + ButtonType, + Builder, + CustomDialogController, + DismissDialogAction, + DialogAlignment, + $r, + Resource, + Entry, + TextInput, + Scroller, + Flex, + HorizontalAlign, + SafeAreaType, + SafeAreaEdge, + FlexWrap, + TextAlign, + ForEach, + Scroll, + Color, + Span, + ItemAlign, + Margin +} from "@ohos.arkui.component"; // TextAttribute should be insert by ui-plugins +import { State, Link, StorageLink, Consume } from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import hilog from '@ohos.hilog'; +import { Context, UIContext } from '@ohos.arkui.UIContext'; +import { Month, MonthDataSource } from '../components/MonthDataSource'; + +const ELEMENTS_MARGIN_L = 24; +const ELEMENTS_MARGIN_M = 8; +const TRANSITION_DURATION = 200; +const MONDAY = '一'; +const TUESDAY = '二'; +const WEDNESDAY = '三'; +const THURSDAY = '四'; +const FRIDAY = '五'; +const SATURDAY = '六'; +const SUNDAY = '日'; +const WEEK: string[] = [SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY]; // 设置日历周,从周日开始 +const MONTH: string = '月'; +const YEAR: string = '年'; +const MONTHS = 12; +const JANUARY = 1; +const WEEK_NUMBER = 7; +const MONTH_NUMBER = 35; +const GRID_HEIGHT_L = 360; +const GRID_HEIGHT_M = 300; +const ELEMENTS_MARGIN = 12; + +@Entry +@Component +export struct CalendarView { + private week: string[] = ['日', '一', '二', '三', '四', '五', '六']; // 设置日历周,从周日开始 + @State dateModel: DateModel = new DateModel(0, 0, 0, 0); // 初始化dateModel数据 + @State flag: boolean = false; + @State contentData: MonthDataSource = new MonthDataSource(); // 列表数据 + nowDate: Date = new Date(); + currentMonth: number = this.nowDate.getMonth() + 1; // 当前月份 + currentDay: number = this.nowDate.getDate(); // 当前日 + currentYear: number = this.nowDate.getFullYear(); // 当前年份 + currentWeekDay: number = new Date(this.currentYear, this.currentMonth - 1, this.currentDay).getDay(); // 当前周几 + private scroller: Scroller = new Scroller(); // 二级列表Scroller对象 + @State nextMonth: number = 1; // 初始化下一个月月份 + @State nextYear: number = 1; // 初始化下一个月年份 + @State nextMonthDay: number[] = new Array(); // 初始化下一个月的日期排列数组 + @State currentMonthDay: number[] = new Array(); // 初始化当前月的日期排列数组 + + // 获取当前日期 + aboutToAppear(): void { + this.dateModel = getRealTimeDate(); // 获取当前年月日信息 + this.currentMonth = this.dateModel.month; // 获取当前月份 + this.currentDay = this.dateModel.day; // 获取当前日 + this.currentYear = this.dateModel.year; // 获取当前年份 + + this.currentMonthDay = getMonthDate(this.currentMonth, this.currentYear); + // 如果下个月是在下一年,则下个月是1月份,年份要+1 + if (this.currentMonth === MONTHS) { + this.nextMonth = JANUARY; + this.nextYear = this.currentYear + 1; + } + // 如果下个月是还是当前年,则月份+1,年份不变 + else { + this.nextMonth = this.currentMonth + 1; + this.nextYear = this.currentYear; + } + this.nextMonthDay = getMonthDate(this.nextMonth, this.nextYear); + // 获取当前月和下个月的日期数据 + const months: Month = + { + month: `${this.currentYear}年 ${this.currentMonth}月`, + num: this.currentMonth, + days: this.currentMonthDay + } + const months2: Month = + { + month: `${this.nextYear}年 ${this.nextMonth}月`, + num: this.nextMonth, + days: this.nextMonthDay + } + this.contentData.pushData(months); + this.contentData.pushData(months2); + } + + @State strss: string | Resource = $r('app.string.customcalendarpickerdialog_departure'); + + @Builder + calendarMainView() { + Column() { + Column() { + // 出发地和目的地显示 + Row() { + Text($r('app.string.customcalendarpickerdialog_departure')) + .fontSize(20) + Image($r("app.media.app_icon")) + .height(20) + .width(20) + Text($r('app.string.customcalendarpickerdialog_destination')) + .fontSize(20) + } + .justifyContent(FlexAlign.SpaceBetween) + .width('100%') + + // 当前日期显示 + Row() { + Text(`${this.dateModel.month}月${this.dateModel.day}日`) + .fontSize(20) + Text(`星期${this.week[this.dateModel.week]}`) + .fontSize(20) + } + .id('calender_click') + .justifyContent(FlexAlign.Start) + .width('100%') + .margin(8) + .onClick((e: ClickEvent) => { + // 点击当前日期后打开自定义弹窗显示日历 + hilog.info(0x0000, 'testTag', '查询车票按钮显示 onClick'); + this.flag = !this.flag; + }) + + // 查询车票按钮显示 + Button($r('app.string.customcalendarpickerdialog_check_ticket')) + .fontSize(20) + .width('100%') + .onClick((e: ClickEvent) => { + }) + } + .margin(10) + .borderRadius($r('app.string.ohos_id_corner_radius_default_m')) + + Flex({ wrap: FlexWrap.Wrap }) { + Text($r('app.string.customcalendarpickerdialog_departure_date')) + .fontSize(20) + .height(20).width("100%") + .textAlign(TextAlign.Center) + // 显示周信息,从周日开始到周六 + ForEach(WEEK, (weekday: string) => { + Text(weekday) + .fontSize(20) + .width(50) + .height(30) + .fontColor(weekday === SUNDAY || weekday === SATURDAY ? Color.Red : Color.Black) + .borderRadius(10) + .textAlign(TextAlign.Center) + .layoutWeight(1) + }) + List() { + ForEach(this.contentData.dataArray, (monthItem: Month) => { + ListItem() { + Flex({ wrap: FlexWrap.Wrap }) { + // 月份信息 + Text(monthItem.month) + .width("100%") + .height(40) + .fontSize(20) + .fontColor(Color.Black) + .backgroundColor($r("app.color.highlyloadedcomponentrender_color_year_background")) + .textAlign(TextAlign.Center) + .id('id_highly_loaded_component_render_title') + // 日期信息 + ForEach(monthItem.days, (day: number, index: number) => { + Text() { + Span(JSON.stringify(day)) + .fontSize(20) + } + .height(50) + .width(50) + .opacity(day === 0 ? 0 : 1) + .fontColor(day < this.currentDay && monthItem.num === this.currentMonth ? Color.Grey : + Color.Black) + .borderRadius(10) + .textAlign(TextAlign.Center) + .backgroundColor(day === this.currentDay && monthItem.num === this.currentMonth ? + $r('app.color.ohos_id_color_palette9') : Color.Transparent) + .onClick((e: ClickEvent) => { + if (day >= this.currentDay || monthItem.num > this.currentMonth || + Number(monthItem.month.substring(0, 4)) > this.currentYear) { + let weekIndex = monthItem.days.indexOf(day) % WEEK_NUMBER; // 将当前日转换成星期显示 + let dateModelTmp: DateModel = new DateModel(0, 0, 0, 0); + dateModelTmp.day = day; + dateModelTmp.week = weekIndex; + dateModelTmp.month = monthItem.num; + dateModelTmp.year = Number(monthItem.month.substring(0, 4)); + this.dateModel = dateModelTmp; + if (this.flag == true) { + this.flag = false; + } + } + }) + }) + }.width("100%") + } + }) + } + .width("100%") + .height("100%") + .backgroundColor($r('app.color.ohos_id_color_background')) + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + } + .width("100%") + .height("60%") + .margin(10) + .opacity(this.flag === true ? 1 : 0) + .borderRadius($r('app.string.ohos_id_corner_radius_default_m')) + }.height("100%") + } + + build() { + Column() { + this.calendarMainView(); + } + .width('100%') + .height('100%') + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/Example3.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/Example3.ets new file mode 100644 index 0000000000000000000000000000000000000000..dfbaaebb4aa3b771e4d4f9e5cb496c234a001631 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/Example3.ets @@ -0,0 +1,87 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { + memo, + __memo_context_type, + __memo_id_type +} from "@ohos.arkui.stateManagement" // should be insert by ui-plugins +import { + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + Row, + TextAlign, + Entry +} from "@ohos.arkui.component"; // TextAttribute should be insert by ui-plugins +import { + State, + Link, + StateDecoratedVariable, + MutableState, + stateOf, + observableProxy +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import hilog from '@ohos.hilog'; +import { Context, UIContext } from '@ohos.arkui.UIContext'; +import { ShoppingCart } from './view/ShoppingCart'; + +@Entry +@Component +struct Example3Test { + aboutToAppear() { + + } + + build() { + Column() { + Row() { + Text("← 返回").fontSize(20) + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().back(); + }).width("100%") + }.height("5%") + + ShoppingCart(); + } + } +} + +export class ComExampleTrivialApplication extends UserView { + getBuilder() { + hilog.info(0x0000, 'testTag', 'getBuilder'); + let wrapper = @memo() => + { + hilog.info(0x0000, 'testTag', 'Example3Test'); + Example3Test(undefined); + } + return wrapper; + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/common/CommonText.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/common/CommonText.ets new file mode 100644 index 0000000000000000000000000000000000000000..6409ad445849e61dd9e3c8b827424fe557a83d74 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/common/CommonText.ets @@ -0,0 +1,165 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { memo, __memo_context_type, __memo_id_type } from '@ohos.arkui.stateManagement' +import { + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + AttributeModifier, + RowAttribute, + ImageAttribute, + CheckboxAttribute, + Row, + Checkbox, + $r, + Resource, + Image, + TextAlign, + FlexAlign +} from '@ohos.arkui.component' +import { + State, + Consume, + StateDecoratedVariable, + MutableState, + stateOf, + observableProxy +} from '@ohos.arkui.stateManagement' +import hilog from '@ohos.hilog' +import promptAction from '@ohos.promptAction'; + +const COLUMN_SPACE = 10; // column间隙 + +/** + * 自定义封装公共文本组件 + */ +@Component +export struct CommonText { + build() { + Row() { + Text($r('app.string.dynamicattributes_text_one')) + .fontSize(12) + .fontColor($r('app.color.dynamicattributes_orange')) + .textAlign(TextAlign.Center) + Text($r('app.string.dynamicattributes_text_two')) + .fontSize(12) + .fontColor($r('app.color.dynamicattributes_orange')) + .textAlign(TextAlign.Center) + .margin(10); + Text($r('app.string.dynamicattributes_text_three')) + .fontSize(12) + .fontColor($r('app.color.dynamicattributes_orange')) + .textAlign(TextAlign.Center) + }.width($r('app.string.dynamicattributes_max_size')) + } +} + +/** + * 自定义封装底部bar组件 + */ +@Component +export struct BottomBar { + @State buttonName: Resource = $r('app.string.dynamicattributes_settlement'); + @State barType: BarType = BarType.SHOPPING_CART; + + build() { + Row() { + Column() { + if (this.barType === BarType.DETAILS) { + Button($r('app.string.dynamicattributes_add_cart')) + .height(30) + .width(90) + .backgroundColor(($r('app.color.dynamicattributes_orange'))) + .onClick((e: ClickEvent) => { + }) + } + } + + Button(this.buttonName) + .height(30) + .width(90) + .backgroundColor(($r('app.color.dynamicattributes_orange'))) + .onClick((e: ClickEvent) => { + }) + } + .height(60) + .width($r('app.string.dynamicattributes_max_size')) + .padding(15) + .backgroundColor($r('app.color.dynamicattributes_barColor')) + .justifyContent(FlexAlign.End) + } +} + +/** + * 自定义封装图文组件 + */ +@Component +export struct ImageText { + @State item: string | Resource = $r('app.string.dynamicattributes_text'); + @State textOneContent: string | Resource = $r('app.string.dynamicattributes_text'); + @State textTwoContent: string | Resource = $r('app.string.dynamicattributes_text'); + @State textThreeContent: string | Resource = $r('app.string.dynamicattributes_text'); + @State imageSrc: Resource = $r('app.media.icon'); + + build() { + Row() { + Row() { + Image($r('app.media.icon')) + .height(100) + .width(100) + .borderRadius(15) + .onClick((e: ClickEvent) => { + }) + } + + Column() { + Text(this.item) + .fontSize(20).width($r('app.string.dynamicattributes_max_size')) + Text(this.textThreeContent) + .fontSize(20).width($r('app.string.dynamicattributes_max_size')) + CommonText() + Text(this.textOneContent) + .fontSize(20).width($r('app.string.dynamicattributes_max_size')) + .fontColor($r('app.color.dynamicattributes_orange')) + }.margin(15) + } + .width($r('app.string.dynamicattributes_max_size')) + .height($r('app.string.dynamicattributes_max_size')) + } +} + +/* + 枚举底部bar类型 +*/ +export enum BarType { + SHOPPING_CART, // 购物车 + DETAILS, // 详情页 +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/common/LazyForEach.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/common/LazyForEach.ets new file mode 100644 index 0000000000000000000000000000000000000000..e1c4e89ce5ff3e696306379b29a8f5c082bdb30b --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/common/LazyForEach.ets @@ -0,0 +1,171 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { memo, __memo_context_type, __memo_id_type } from '@ohos.arkui.stateManagement'; +import { + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + IDataSource, + DataChangeListener +} from '@ohos.arkui.component'; +import { State, StateDecoratedVariable, MutableState, stateOf, observableProxy } from '@ohos.arkui.stateManagement'; + +class BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: string[] = []; + + /** + * 获取数组长度。 + * @returns {number} 返回数组长度。 + */ + public totalCount(): number { + return 0; + } + + /** + * 获取指定索引数据。 + * @param {number} index - 索引值。 + * @returns {string} 返回指定索引数据。 + */ + public getData(index: number): string { + return this.originDataArray[index]; + } + + /** + * 为LazyForEach组件向其数据源处添加listener监听。 + * @param {DataChangeListener} listener - 监听对象。 + */ + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + console.info('add listener'); + this.listeners.push(listener); + } + } + + /** + * 为对应的LazyForEach组件在数据源处去除listener监听。 + * @param {DataChangeListener} listener - 监听对象。 + */ + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + console.info('remove listener'); + this.listeners.splice(pos, 1); + } + } + + /** + * 通知LazyForEach组件需要在index对应索引处添加子组件。 + * @param {number} index - 索引值。 + */ + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + /** + * 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件。 + * @param {number} index - 索引值。 + */ + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + /** + * 通知LazyForEach组件需要在index对应索引处删除该子组件 + * @param {number} index - 索引值。 + */ + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + /** + * 通知LazyForEach组件将from索引和to索引处的子组件进行交换 + * @param {number} from - 起始值。 + * @param {number} to - 终点值。 + */ + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } +} + +/** + * 继承自BasicDataSource的子类,重写了方法。 + * + * @class + * @extends {BasicDataSource} + */ +export class MyDataSource extends BasicDataSource { + public dataArray: string[] = []; + + /** + * 获取数组长度。 + * @returns {number} 返回数组长度。 + */ + public totalCount(): number { + return this.dataArray.length; + } + + /** + * 获取指定索引数据。 + * @param {number} index - 索引值。 + * @returns {string} 返回指定索引数据。 + */ + public getData(index: number): string { + return this.dataArray[index]; + } + + /** + * 改变单个数据。 + * @param {number} index - 索引值。 + * @param {string} data - 修改后的值。 + */ + public addData(index: number, data: string): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + /** + * 添加数据。 + * @param {string} data - 需要添加的数据。 + */ + public pushData(data: string): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/view/Details.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/view/Details.ets new file mode 100644 index 0000000000000000000000000000000000000000..e455de9873e62d3643dfd07309d7b306748fe603 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/view/Details.ets @@ -0,0 +1,127 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { memo, __memo_context_type, __memo_id_type } from '@ohos.arkui.stateManagement'; +import { + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + Stack, + Row, + FlexAlign, + Image, + $r, + FontWeight, + Color, + Entry, + SafeAreaEdge, + SafeAreaType +} from '@ohos.arkui.component'; +import { State, StateDecoratedVariable, MutableState, stateOf, observableProxy } from '@ohos.arkui.stateManagement'; +import hilog from '@ohos.hilog'; +import { BarType, BottomBar, CommonText } from '../common/CommonText'; + +const COLUMN_SPACE = 20; // column间隙 +const TEXT_SIZE = 15; // 自定义组件中text大小 + +@Entry +@Component +export struct Details { + build() { + Column() { + Column() { + Text("← 返回").fontSize(20) + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().back() + }).width("100%").height("5%") + + // 商品图片 + Image($r('app.media.icon')) + .height('60%').width("100%") + // 商品详情区 + ProductInfo() + }.width('100%').height('95%') + + // 底部购买区 + BottomBar({ + buttonName: $r('app.string.dynamicattributes_settlement'), + barType: BarType.DETAILS + }) + }.width('100%').height('100%').backgroundColor(Color.White) + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) + } +} + +@Component +struct ProductInfo { + build() { + Row() { + Column() { + Row() { + Text($r('app.string.dynamicattributes_commodity_price'))// 动态设置组件样式 + .width(100) + .fontSize(30) + Text($r('app.string.dynamicattributes_sold')) + .fontSize(15) + .width(60) + } + .width($r('app.string.dynamicattributes_max_size')) + .justifyContent(FlexAlign.SpaceBetween) + + Row() { + Text($r('app.string.dynamicattributes_full_reduction')) + .fontColor($r('app.color.dynamicattributes_red')) + .fontSize(20) + + Button($r('app.string.dynamicattributes_coupon_collection')) + .height(20) + .backgroundColor($r('app.color.dynamicattributes_red')) + } + .justifyContent(FlexAlign.SpaceBetween) + .width($r('app.string.dynamicattributes_max_size')) + + Text($r('app.string.dynamicattributes_commodity_name')) + .fontWeight(FontWeight.Bold) + .fontSize(25) + .width("100%") + Text($r('app.string.dynamicattributes_commodity_model')) + .fontSize(25) + .fontColor(Color.Gray) + .width("100%") + CommonText() + } + .backgroundColor($r('app.color.dynamicattributes_white')) + .height("100%") + } + .padding(10) + .height("40%") + .width($r('app.string.dynamicattributes_max_size')) + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/view/ShoppingCart.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/view/ShoppingCart.ets new file mode 100644 index 0000000000000000000000000000000000000000..a6a0b75a737296af5d6e65ca6fc504c38995c2ea --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example3/view/ShoppingCart.ets @@ -0,0 +1,150 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { memo, __memo_context_type, __memo_id_type } from '@ohos.arkui.stateManagement'; +import { + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + PixelMap, + ResourceStr, + DrawableDescriptor, + Row, + Checkbox, + Stack, + NavDestination, + FontWeight, + Alignment, + List, + NavPathStack, + Builder, + Navigation, + $r, + SafeAreaType, + SafeAreaEdge, + Color, + Scroll, + ForEach, + LazyForEach, + ListItem +} from '@ohos.arkui.component'; +import { + State, + StateDecoratedVariable, + MutableState, + stateOf, + observableProxy, + Prop +} from '@ohos.arkui.stateManagement'; + +import hilog from '@ohos.hilog'; +import { Context, UIContext } from '@ohos.arkui.UIContext'; +import { MyDataSource } from '../common/LazyForEach'; +import { BottomBar, ImageText } from '../common/CommonText'; +import { Details } from './Details'; + +@Component +export struct ShoppingCart { + private data: MyDataSource = new MyDataSource(); + + aboutToAppear() { + for (let i = 1; i <= 20; i++) { + this.data.pushData("商品" + i); + } + } + + build() { + Column() { + Column() { + Text($r('app.string.dynamicattributes_shopping_cart')) + .fontSize(20) + .fontWeight(FontWeight.Bold) + .width("100%") + .height(50) + .padding(20) + .align(Alignment.Bottom) + List() { + LazyForEach(this.data, (item: string) => { + ListItem() { + ShoppingInfo({ item: item }); + }.width('100%') + }) + }.width('100%') + }.backgroundColor("#ffc4c6c6") + .height('90%') + .width('100%') + + BottomBar({ + buttonName: $r('app.string.dynamicattributes_settlement') + }) + } + .width('100%') + .height('100%') + .backgroundColor(Color.White) + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) + } +} + + +@Component +struct ShoppingInfo { + @Prop item: string = ' '; + + build() { + Column() { + // 店铺信息 + Row() { + Row() + .borderRadius(5) + .width(20) + .height(20) + .backgroundColor($r('app.color.dynamicattributes_iconColor')) + + Text($r('app.string.dynamicattributes_store_name')) + .fontSize(15) + .margin($r('app.float.dynamicattributes_float_5')) + } + .width(($r('app.string.dynamicattributes_max_size'))) + .height($r('app.float.dynamicattributes_float_20')) + + // 商品信息 + Row() { + ImageText({ item: this.item }) + }.onClick((e: ClickEvent) => { + this.getUIContext().getRouter().pushUrl({ url: "pages/Example3/view/Details" }); + }) + } + .padding($r('app.float.dynamicattributes_float_15')) + .margin(10) + .height($r('app.float.dynamicattributes_float_160')) + .backgroundColor($r('app.color.dynamicattributes_white')) + .borderRadius($r('app.float.dynamicattributes_float_20')) + } +} diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/Example4.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/Example4.ets new file mode 100644 index 0000000000000000000000000000000000000000..afdf419d684903a8a2469cf21acc92058b2ba74d --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/Example4.ets @@ -0,0 +1,85 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { + memo, + __memo_context_type, + __memo_id_type +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import { + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + Row, + Entry +} from "@ohos.arkui.component"; // TextAttribute should be insert by ui-plugins +import { + State, + Link, + StateDecoratedVariable, + MutableState, + stateOf, + observableProxy +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import hilog from '@ohos.hilog'; +import { Context, UIContext } from '@ohos.arkui.UIContext'; +import { ReusePage } from './ReusePage'; + +@Entry +@Component +struct Example4Test { + aboutToAppear() { + } + + build() { + Column() { + Row() { + Text("← 返回").fontSize(20) + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().back(); + }).width("100%") + }.height("5%") + + ReusePage(); + } + } +} + +export class ComExampleTrivialApplication extends UserView { + getBuilder() { + hilog.info(0x0000, 'testTag', 'getBuilder'); + let wrapper = @memo() => + { + hilog.info(0x0000, 'testTag', 'Example4Test'); + Example4Test(undefined); + } + return wrapper; + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/GetDate.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/GetDate.ets new file mode 100644 index 0000000000000000000000000000000000000000..abdabd60b286cfe7f4b94000e474e861fea6c131 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/GetDate.ets @@ -0,0 +1,80 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { + memo, + __memo_context_type, + __memo_id_type +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import { + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + Entry +} from "@ohos.arkui.component"; // TextAttribute should be insert by ui-plugins + +import { + State, + Link, + StateDecoratedVariable, + MutableState, + stateOf, + observableProxy +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import hilog from '@ohos.hilog'; + +const SATURDAY: number = 6; // 日历表上周六对应的序列号,从周日开始算起,取值0~6 + +/* + * 根据指定年份和月份获取该月在日历表上的日期排布数据 + * @param {number} specifiedMonth - 指定月份 + * @param {number} specifiedYear - 指定年份 +// */ +export function getMonthDate(specifiedMonth: number, specifiedYear: number): 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.push(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; +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/MonthDataSource.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/MonthDataSource.ets new file mode 100644 index 0000000000000000000000000000000000000000..9bb33f5fe7bf2f05ac5353d83db112c6a14953be --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/MonthDataSource.ets @@ -0,0 +1,178 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import { + memo, + __memo_context_type, + __memo_id_type +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import { + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + Entry, + IDataSource, + DataChangeListener +} from "@ohos.arkui.component"; // TextAttribute should be insert by ui-plugins +import { + State, + Link, + StateDecoratedVariable, + MutableState, + stateOf, + observableProxy +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins + +export interface Month { + month: string; // 具体年月 + num: number; // 月份 + days: number[]; // 该月日期 + year: number; // 年份 +} + +/** + * Basic implementation of IDataSource to handle data listener + * + * @class + * @implements {IDataSource} + */ +export class MonthDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + public dataArray: Month[] = new Array(); + + /** + * 获取数组长度。 + * @returns {number} 返回数组长度。 + */ + public totalCount(): number { + return this.dataArray.length; + } + + /** + * 获取指定索引数据。 + * @param {number} index - 索引值。 + * @returns {CustomDataType} 返回指定索引数据。 + */ + public getData(index: number): Month { + return this.dataArray[index]; + } + + public setData(index: number, data: Month[]) { + + } + + /** + * 为LazyForEach组件向其数据源处添加listener监听。 + * @param {DataChangeListener} listener - 监听对象。 + */ + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + /** + * 为对应的LazyForEach组件在数据源处去除listener监听。 + * @param {DataChangeListener} listener - 监听对象。 + */ + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + /** + * 通知LazyForEach组件需要在index对应索引处添加子组件。 + * @param {number} index - 索引值。 + */ + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + /** + * 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件。 + * @param {number} index - 索引值。 + */ + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + /** + * 通知LazyForEach组件需要在index对应索引处删除该子组件 + * @param {number} index - 索引值。 + */ + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + /** + * 通知LazyForEach组件将from索引和to索引处的子组件进行交换 + * @param {number} from - 起始值。 + * @param {number} to - 终点值。 + */ + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } + + /** + * 改变单个数据。 + * @param {number} index - 索引值。 + * @param {CustomDataType} data - 修改后的值。 + */ + public addData(index: number, data: Month): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + /** + * 添加数据。 + * @param {CustomDataType} data - 需要添加的数据。 + */ + public pushData(data: Month): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/ReusePage.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/ReusePage.ets new file mode 100644 index 0000000000000000000000000000000000000000..374961140ee38c72cf44a50f0f330453dbbe5b54 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Example4/ReusePage.ets @@ -0,0 +1,217 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import hilog from '@ohos.hilog' +import { getMonthDate } from './GetDate'; +import { Month, MonthDataSource } from './MonthDataSource'; +import { + memo, + __memo_context_type, + __memo_id_type +} from "@ohos.arkui.stateManagement" // should be insert by ui-plugins +import { + Text, + TextAttribute, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView, + Flex, + ItemAlign, + ForEach, + FlexWrap, + Entry, + TextAlign, + $r, + Color, + HorizontalAlign, + SafeAreaType, + Row, + LazyForEach, + SafeAreaEdge, + Span, + List, + EdgeEffect, + BarState, + Scroll, + Scroller, + ExpectedFrameRateRange, + ListItem +} from "@ohos.arkui.component"; // TextAttribute should be insert by ui-plugins +import { + State, + Link, + StateDecoratedVariable, + MutableState, + stateOf, + observableProxy +} from "@ohos.arkui.stateManagement"; // should be insert by ui-plugins +import { Context, UIContext } from '@ohos.arkui.UIContext'; + +const MONDAY = '一'; +const TUESDAY = '二'; +const WEDNESDAY = '三'; +const THURSDAY = '四'; +const FRIDAY = '五'; +const SATURDAY = '六'; +const SUNDAY = '日'; +const WEEK: string[] = [SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY]; // 设置日历周,从周日开始 +const MONTH: string = '月'; +const YEAR: string = '年'; + +/** + * 通过组件复用,加载每个月份的数据,当数据量较多时,快速滑动到底部,会出现掉帧的情况。 + */ + +@Component +export struct ReusePage { + @State contentData: MonthDataSource = new MonthDataSource(); // 列表数据 + nowDate: Date = new Date(); + currentMonth: number = this.nowDate.getMonth() + 1; // 当前月份 + currentDay: number = this.nowDate.getDate(); // 当前日 + currentYear: number = this.nowDate.getFullYear(); // 当前年份 + currentWeekDay: number = new Date(this.currentYear, this.currentMonth - 1, this.currentDay).getDay(); // 当前周几 + private scroller: Scroller = new Scroller(); // 二级列表Scroller对象 + + // 初始化日历中一年的数据 + initCalenderData() { + for (let k = this.currentYear; k < 2035; ++k) { + for (let i = 1; i <= 12; i++) { + // 获取每个月的日数据 + const monthDays: number[] = getMonthDate(i, k); + const month: Month = { + month: i + MONTH, + num: i, + days: monthDays, + year: k + }; + this.contentData.pushData(month); + } + } + } + + aboutToAppear() { + this.initCalenderData(); + } + + build() { + Column() { + Text(this.currentYear + YEAR) + .width("100%") + .height(40) + .fontSize(20) + .fontColor(Color.Black) + .backgroundColor($r("app.color.highlyloadedcomponentrender_color_year_background")) + .textAlign(TextAlign.Center) + .id('id_highly_loaded_component_render_title') + List() { + LazyForEach(this.contentData, (monthItem: Month) => { + ListItem() { + ItemView({ + monthItem: monthItem, + currentMonth: this.currentMonth, + currentDay: this.currentDay, + currentYear: this.currentYear + }) + }.width("100%") + }) + } + .width("100%") + } + .width("100%") + .height("100%") + .backgroundColor($r('app.color.ohos_id_color_background')) + .alignItems(HorizontalAlign.Center) + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + } +} + +// @Reusable +@Component +struct ItemView { + @State monthItem: Month = { + month: '', + num: 0, + days: [], + year: 0 + } as Month; + private currentMonth: number = 0; + private currentYear: number = 0; // 当前年份 + private currentDay: number = 0; + private temp: Month[] = Array(); + private step: number = 0; + private maxStep: number = 2; // 最多执行的帧数 + readonly MAX_EVERY_FRAME: number = 5; // 每帧最多处理的数据量 + @State month: string = ""; + @State monthNumber: number = 0; + @State days: number[] = Array(); + @State year: number = 0; + + build() { + Flex({ wrap: FlexWrap.Wrap }) { + // 月份信息 + Text(this.monthItem.month) + .fontSize(25) + .height(40) + .fontColor(Color.Black) + .width("100%") + .textAlign(TextAlign.Start) + .layoutWeight(1) + + ForEach(WEEK, (weekday: string) => { + Text(weekday) + .fontSize(20) + .width(50) + .height(30) + .fontColor(weekday === SUNDAY || weekday === SATURDAY ? Color.Red : Color.Black) + .borderRadius(10) + .textAlign(TextAlign.Center) + .layoutWeight(1) + }) + // 日期信息 + ForEach(this.monthItem.days, (day: number, index: number) => { + Text() { + Span(JSON.stringify(day)) + .fontSize(20) + } + .height(50) + .width(50) + .opacity(day === 0 ? 0 : 1) + .fontColor(Color.Black) + .borderRadius(10) + .textAlign(TextAlign.Center) + .backgroundColor(day === this.currentDay && this.monthItem.num === this.currentMonth && + this.monthItem.year === this.currentYear ? + $r('app.color.ohos_id_color_palette9') : Color.Transparent) + .layoutWeight(1) + }) + } + .alignSelf(ItemAlign.Start) + .backgroundColor(Color.Transparent) + .width(350) + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Index.ets b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..79a7248ead78c37f48c9642e56688c1168c39ebc --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,71 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +import { memo, __memo_context_type, __memo_id_type } from "@ohos.arkui.stateManagement" // should be insert by ui-plugins +import { Text, TextAttribute, Column, Component, Button, ButtonAttribute, ClickEvent, UserView, Row, TextAlign, Visibility, + List, WordBreak,ListItem,TextInput, InputType,TextOverflow, Image, HorizontalAlign,Tabs,$r,TabContent, Progress, ProgressType} from "@ohos.arkui.component" // TextAttribute should be insert by ui-plugins +import { State, Link, StateDecoratedVariable, MutableState, stateOf, observableProxy } from "@ohos.arkui.stateManagement" // should be insert by ui-plugins +import hilog from '@ohos.hilog' +import common from '@ohos.app.ability.common'; +import {globalContext} from '../entryability/GlobalContext'; +import { Context,UIContext} from '@ohos.arkui.UIContext' + +@Component +struct MyStateSample { + private context :common.UIAbilityContext = globalContext.getAbilityContext(); + build() { + Column() { + Button($r('app.string.example4')) + .onClick((e: ClickEvent)=>{ + this.getUIContext().getRouter().pushUrl({url:"pages/Example4/Example4"}) + }).fontSize(18).margin(15).width("100%") + Button($r('app.string.example3')) + .onClick((e: ClickEvent)=>{ + this.getUIContext().getRouter().pushUrl({url:"pages/Example3/Example3"}) + }).fontSize(20).width("100%") + Button($r('app.string.example2')) + .onClick((e: ClickEvent)=>{ + this.getUIContext().getRouter().pushUrl({url:"pages/Example2/Example2"}) + }).fontSize(20).margin(15).width("100%") + Button($r('app.string.example1')) + .onClick((e: ClickEvent)=>{ + this.getUIContext().getRouter().pushUrl({url:"pages/Example1/Example1"}) + }).fontSize(20).width("100%") + } + .padding(15) + .width("100%") + } +} + +export class ComExampleTrivialApplication extends UserView { + getBuilder() { + hilog.info(0x0000, 'testTag', 'getBuilder'); + let wrapper = @memo () => { + hilog.info(0x0000, 'testTag', 'MyStateSample'); + MyStateSample(undefined) + } + return wrapper; + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/module.json5 b/code/ArkTS1.2/ComponentSample/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f95f9a6e69c03b1b6da379b36fc7aa9ee2c41ac4 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/module.json5 @@ -0,0 +1,64 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/color.json b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..2d7ab60c091671985af6c3d8bac9f4a567cbf694 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/color.json @@ -0,0 +1,88 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + }, + { + "name": "ohos_id_color_sub_background", + "value": "#F1F3F5" + }, + { + "name": "ohos_id_color_background", + "value": "#FFFFFF" + }, + { + "name": "ohos_id_color_warning", + "value": "#E84026" + }, + { + "name": "ohos_id_color_text_primary", + "value": "#E5000000" + }, + { + "name": "ohos_id_color_palette9", + "value": "#ED6F21" + }, + { + "name": "ohos_id_color_text_secondary", + "value": "#99000000" + }, + { + "name": "highlyloadedcomponentrender_color_year_background", + "value": "#33000000" + }, + { + "name": "dynamicattributes_white", + "value": "#FFFFFF" + }, + { + "name": "dynamicattributes_red", + "value": "#FF0000" + }, + { + "name": "dynamicattributes_orange", + "value": "#FF4500" + }, + { + "name": "dynamicattributes_buttonColor", + "value": "#EE7600" + }, + { + "name": "dynamicattributes_iconColor", + "value": "#B22222" + }, + { + "name": "dynamicattributes_imageColor", + "value": "#ccc" + }, + { + "name": "dynamicattributes_selectColor", + "value": "#FF8247" + }, + { + "name": "dynamicattributes_barColor", + "value": "#F5F5F5" + }, + { + "name": "calendar_switch_border_color", + "value": "#24A844" + }, + { + "name": "calendar_switch_segment_button_bgcolor", + "value": "#FFFEFEFE" + }, + { + "name": "calendar_switch_segment_button_font_color", + "value": "#4e4e4e" + }, + { + "name": "calendar_switch_segment_button_row_bgcolor", + "value": "#e7e7e7" + }, + { + "name": "calendar_switch_schedule_point_color", + "value": "#ffababab" + } + ] +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/float.json b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..5cccb549a0248f44ada3a242006b67d76db9c525 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/float.json @@ -0,0 +1,60 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + }, + { + "name": "dynamicattributes_float_1", + "value": "1vp" + }, + { + "name": "dynamicattributes_float_5", + "value": "5vp" + }, + { + "name": "dynamicattributes_float_10", + "value": "10vp" + }, + { + "name": "dynamicattributes_float_12", + "value": "12vp" + }, + { + "name": "dynamicattributes_float_15", + "value": "15vp" + }, + { + "name": "dynamicattributes_float_20", + "value": "20vp" + }, + { + "name": "dynamicattributes_float_25", + "value": "25vp" + }, + { + "name": "dynamicattributes_float_30", + "value": "30vp" + }, + { + "name": "dynamicattributes_float_50", + "value": "50vp" + }, + { + "name": "dynamicattributes_float_60", + "value": "60vp" + }, + { + "name": "dynamicattributes_float_90", + "value": "90" + }, + { + "name": "dynamicattributes_float_100", + "value": "100vp" + }, + { + "name": "dynamicattributes_float_160", + "value": "160vp" + } + ] +} diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/integer.json b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/integer.json new file mode 100644 index 0000000000000000000000000000000000000000..eb56fd598c3b9b1fe165e4f600a2e4ebab0fda39 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/integer.json @@ -0,0 +1,256 @@ +{ + "integer": [ + { + "name": "customcalendarpickerdialog_train_image_size", + "value": 20 + }, + { + "name": "customcalendarpickerdialog_check_button_height", + "value": 40 + }, + { + "name": "customcalendarpickerdialog_card_padding", + "value": 16 + }, + { + "name": "customcalendarpickerdialog_text_height", + "value": 40 + }, + { + "name": "customcalendarpickerdialog_month_text", + "value": 240 + }, + { + "name": "highlyloadedcomponentrender_list_padding_left", + "value": 10 + }, + { + "name": "highlyloadedcomponentrender_list_padding_right", + "value": 10 + }, + { + "name": "highlyloadedcomponentrender_column_padding_bottom", + "value": 12 + }, + { + "name": "highlyloadedcomponentrender_year_height", + "value": 40 + }, + { + "name": "highlyloadedcomponentrender_month_font_size", + "value": 25 + }, + { + "name": "highlyloadedcomponentrender_month_height", + "value": 40 + }, + { + "name": "highlyloadedcomponentrender_month_width", + "value": 350 + }, + { + "name": "highlyloadedcomponentrender_month_margin_top", + "value": 5 + }, + { + "name": "highlyloadedcomponentrender_week_font_size", + "value": 20 + }, + { + "name": "highlyloadedcomponentrender_year_font_size", + "value": 20 + }, + { + "name": "highlyloadedcomponentrender_week_height", + "value": 30 + }, + { + "name": "highlyloadedcomponentrender_week_width", + "value": 50 + }, + { + "name": "highlyloadedcomponentrender_week_border_radius", + "value": 10 + }, + { + "name": "highlyloadedcomponentrender_day_font_size", + "value": 20 + }, + { + "name": "highlyloadedcomponentrender_day_lunar_font_size", + "value": 15 + }, + { + "name": "highlyloadedcomponentrender_day_height", + "value": 50 + }, + { + "name": "highlyloadedcomponentrender_day_width", + "value": 50 + }, + { + "name": "highlyloadedcomponentrender_day_border_radius", + "value": 10 + }, + { + "name": "customreusablepool_title_view_padding_left_side", + "value": 20 + },{ + "name": "customreusablepool_title_view_padding_right_side", + "value": 20 + },{ + "name": "customreusablepool_title_view_padding_left", + "value": 10 + },{ + "name": "customreusablepool_title_view_padding_right", + "value": 10 + },{ + "name": "customreusablepool_title_view_list_height", + "value": 30 + },{ + "name": "customreusablepool_home_button_margin_top", + "value": 20 + },{ + "name": "customreusablepool_item_name_margin_top", + "value": 10 + },{ + "name": "customreusablepool_flow_item_comp_border_radius", + "value": 10 + },{ + "name": "customreusablepool_flow_item_comp_name_font_size", + "value": 14 + },{ + "name": "customreusablepool_flow_item_comp_des_font_size", + "value": 12 + },{ + "name": "customreusablepool_flow_swiper_height", + "value": 200 + },{ + "name": "customreusablepool_flow_columns_Gap", + "value": 10 + },{ + "name": "customreusablepool_flow_rows_Gap", + "value": 5 + }, + { + "name": "calendar_switch_size_forty", + "value":40 + }, + { + "name": "calendar_switch_size_ten", + "value":10 + }, + { + "name": "calendar_switch_size_twenty_five", + "value":25 + }, + { + "name": "calendar_switch_size_three", + "value":3 + }, + { + "name": "calendar_switch_size_four", + "value":4 + }, + { + "name": "calendar_switch_size_seven", + "value":7 + }, + { + "name": "calendar_switch_margin_left", + "value":6 + }, + { + "name": "calendar_switch_margin_bottom", + "value":5 + }, + { + "name": "calendar_switch_margin_size_twelve", + "value":12 + }, + { + "name": "calendar_switch_size_fifteen", + "value": 15 + }, + { + "name": "calendar_switch_columns_gap", + "value": 0 + }, + { + "name": "calendar_switch_rows_gap", + "value": 10 + }, + { + "name": "calendar_switch_size_thirty_five", + "value": 35 + }, + { + "name": "calendar_switch_size_fourteen", + "value": 14 + }, + { + "name": "calendar_switch_border_radius", + "value": 20 + }, + { + "name": "calendar_switch_zero", + "value": 0 + }, + { + "name": "calendar_switch_size_eighteen", + "value": 18 + }, + { + "name": "calendar_switch_size_twenty", + "value": 20 + }, + { + "name": "calendar_switch_size_thirty", + "value": 30 + }, + { + "name": "calendar_switch_size_forty_six", + "value": 46 + }, + { + "name": "calendar_switch_size_one", + "value": 1 + }, + { + "name": "calendar_switch_size_forty_eight", + "value": 48 + }, + { + "name": "calendar_switch_size_eighty", + "value": 80 + }, + { + "name": "calendar_switch_size_ninety", + "value": 90 + }, + { + "name": "calendar_switch_size_hundred", + "value": 100 + }, + { + "name": "calendar_switch_size_sixteen", + "value": 16 + }, + { + "name": "calendar_switch_size_twenty_two", + "value": 22 + }, + { + "name": "calendar_switch_size_eight", + "value": 8 + }, + { + "name": "calendar_switch_size_sixty", + "value": 60 + }, + { + "name": "calendar_switch_two_hundred_fifty", + "value": 250 + } + ] +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/string.json b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..067c799f674dc7d653b0cd7e5be2135d5b8ed990 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/element/string.json @@ -0,0 +1,215 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + }, + { + "name": "customcalendarpickerdialog_departure", + "value": "北京" + }, + { + "name": "customcalendarpickerdialog_destination", + "value": "上海" + }, + { + "name": "customcalendarpickerdialog_check_ticket", + "value": "检查车票" + }, + { + "name": "customcalendarpickerdialog_departure_date", + "value": "出发日期" + }, + { + "name": "customcalendarpickerdialog_button_text", + "value": "仅演示,可自行实现业务功能" + }, + { + "name": "customcalendarpickerdialog_week_width", + "value": "14.3%" + }, + { + "name": "customcalendarpickerdialog_calendar_height", + "value": "90%" + }, + { + "name": "ohos_id_text_size_body2", + "value": "14" + }, + { + "name": "ohos_id_corner_radius_default_l", + "value": "16" + }, + { + "name": "ohos_id_corner_radius_default_m", + "value": "12" + }, + { + "name": "ohos_id_text_size_headline", + "value": "20" + }, + { + "name": "ohos_id_text_size_body1", + "value": "14" + }, + { + "name": "percent_100", + "value": "100%" + }, + { + "name": "dynamicattributes_shopping_cart", + "value": "购物车" + },{ + "name": "dynamicattributes_store_name", + "value": "xxx旗舰店" + }, + { + "name": "dynamicattributes_commodity_name", + "value": "商品" + }, + { + "name": "dynamicattributes_commodity_model", + "value": "商品型号" + }, + { + "name": "dynamicattributes_commodity_price", + "value": "¥300" + }, + { + "name": "dynamicattributes_text", + "value": "文本" + }, + { + "name": "dynamicattributes_text_one", + "value": "文本1" + }, + { + "name": "dynamicattributes_text_two", + "value": "文本2" + }, + { + "name": "dynamicattributes_text_three", + "value": "文本3" + }, + { + "name": "dynamicattributes_full_reduction", + "value": "每满300减40" + }, + { + "name": "dynamicattributes_sold", + "value": "已售88" + }, + { + "name": "dynamicattributes_coupon_collection", + "value": "领券" + }, + { + "name": "dynamicattributes_buy_now", + "value": "立即购买" + }, + { + "name": "dynamicattributes_add_cart", + "value": "加入购物车" + }, + { + "name": "dynamicattributes_settlement", + "value": "结算" + }, + { + "name": "dynamicattributes_only_show", + "value": "此样式仅为案例展示" + }, + { + "name": "dynamicattributes_text_proportion", + "value": "40%" + }, + { + "name": "dynamicattributes_image_proportion", + "value": "60%" + }, + { + "name": "dynamicattributes_max_size", + "value": "100%" + }, + { + "name": "dynamicattributes_list_height", + "value": "calc(100% - 50vp)" + }, + { + "name": "customreusablepool_percent_100", + "value": "100%" + }, + { + "name": "customreusablepool_percent_60", + "value": "60%" + }, + { + "name": "customreusablepool_button_normal", + "value": "常规复用" + }, + { + "name": "customreusablepool_button_custom", + "value": "全局自定义组件复用池" + }, + { + "name": "customreusablepool_water_flow_background_color", + "value": "#FAEEE0" + }, + { + "name": "calendar_switch_full_size", + "value": "100%" + }, + { + "name": "calendar_switch_size_twenty_three", + "value": "23%" + }, + { + "name": "calendar_switch_size_twenty_five", + "value": "25%" + }, + { + "name": "calendar_switch_button_style", + "value": "20fp" + }, + { + "name": "calendar_switch_describe", + "value": "说明" + }, + { + "name": "secondarylinkage_secondary_link", + "value": "二级联动" + }, + { + "name": "secondarylinkage_secondary_link_desc", + "value": "当前界面主要展示了通过选择一个列表(一级列表),来更新另一个列表(二级列表)的选项的效果" + }, + { + "name": "secondarylinkage_nomore", + "value": "没有更多了" + }, + { + "name": "example1", + "value": "列表二级联动" + }, + { + "name": "example2", + "value": "自定义日历选择器" + }, + { + "name": "example3", + "value": "跨文件样式复用和组件复用" + }, + { + "name": "example4", + "value": "合理处理高负载组件的渲染文章示例代码" + } + ] +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/background.png b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/background.png differ diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example1.PNG b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example1.PNG new file mode 100644 index 0000000000000000000000000000000000000000..c8752a57e193034ae76e92c305dbf7107257185c Binary files /dev/null and b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example1.PNG differ diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example2.PNG b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example2.PNG new file mode 100644 index 0000000000000000000000000000000000000000..737d1927ff24eabc36a32bbe9701236874d63423 Binary files /dev/null and b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example2.PNG differ diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example3.PNG b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example3.PNG new file mode 100644 index 0000000000000000000000000000000000000000..2cb413a6355d651de06603d7a641edb9452b5f96 Binary files /dev/null and b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example3.PNG differ diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example4.PNG b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example4.PNG new file mode 100644 index 0000000000000000000000000000000000000000..63541569adb03b5f45432a9ea578681ef215928e Binary files /dev/null and b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/example4.PNG differ diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/foreground.png b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/foreground.png differ diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/icon.jpg b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a080ea61211d400b777aecb5e68667e898df5964 Binary files /dev/null and b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/icon.jpg differ diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/layered_image.json b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/main.png b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/main.png new file mode 100644 index 0000000000000000000000000000000000000000..63ccfe01a130f56fb98b6b5e7c7e2f7223193827 Binary files /dev/null and b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/main.png differ diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/startIcon.png b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/startIcon.png differ diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/train_icon.png b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/train_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..44ed5a9bdbbda8701231fb067643a2f9451d03d1 Binary files /dev/null and b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/media/train_icon.png differ diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/profile/backup_config.json b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/profile/main_pages.json b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/code/ArkTS1.2/ComponentSample/entry/src/main/resources/dark/element/color.json b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/code/ArkTS1.2/ComponentSample/hvigor/hvigor-config.json5 b/code/ArkTS1.2/ComponentSample/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..57c58e3641a0b085f39f7f137b9a938ecb20f2fd --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/hvigor/hvigor-config.json5 @@ -0,0 +1,49 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +{ + "modelVersion": "5.0.2", + "dependencies": { + "@ohos/hvigor-ohos-online-sign-plugin": "4.0.2" + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/code/ArkTS1.2/ComponentSample/hvigorfile.ts b/code/ArkTS1.2/ComponentSample/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f435606b5766719f7203539113d84a2b281b0353 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/hvigorfile.ts @@ -0,0 +1,32 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/code/ArkTS1.2/ComponentSample/oh-package.json5 b/code/ArkTS1.2/ComponentSample/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e31dcff151dbff2d8d883823b5de6609fd8c5c28 --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/oh-package.json5 @@ -0,0 +1,36 @@ +/** + * + * Copyright (c) 2025 Huawei Device Co., Ltd. + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice,this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, + * + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +{ + "modelVersion": "5.0.2", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/code/ArkTS1.2/ComponentSample/ohosTest.md b/code/ArkTS1.2/ComponentSample/ohosTest.md new file mode 100644 index 0000000000000000000000000000000000000000..6934f2657f7f73cb19be54c6f9b0663429d01ecf --- /dev/null +++ b/code/ArkTS1.2/ComponentSample/ohosTest.md @@ -0,0 +1,10 @@ +# 组件复用案例测试用例 + +## 用例表 + +| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 | +|-----------------------------------|-------------------------------------|----------------------|------------------------------------|------|------| +| 页面滑动是否正常显示 | 1. 需在真机测试
2. 构建并安装测试hap
3.进入【合理处理高负载组件的渲染文章示例代码】| 在页面上上下滑动 | 页面显示当前年份和日历列表,列表可以正常滑动 | 否 | Pass | +| 购物车页面的list列表跳转商品详情页 | 1. 需在真机测试
2. 构建并安装测试hap
3.进入【跨文件样式复用和组件复用案例】| 点击购物车页面的list列表 | 跳转商品详情页 | 否 | Pass | +| 日历面板切换显示 | 1. 需在真机测试
2. 构建并安装测试hap
3.进入【自定义日历选择器案例】| 1、点击日期时间
2、上下滑动日历
3、点击日期| 1、下方显示近两个月的日期面板,默认当天高亮显示
2、日历数据刷新显示,无卡顿
3、日期面板消失,主页日期变更为选择的日期,当天以前的日期无法点击选中 | 否 | Pass | +| 列表二级联动 | 1. 需在真机测试
2. 构建并安装测试hap
3.进入【列表二级联动】| 1、点击一级列表类别3
2、滑动二级列表到类别5 | 1、二级列表滚动到类别3
2、一级列表选中类别5| 否 | Pass | \ No newline at end of file