diff --git a/code/ArkTS1.2/TabsSample/.gitignore b/code/ArkTS1.2/TabsSample/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/code/ArkTS1.2/TabsSample/.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/TabsSample/AppScope/app.json5 b/code/ArkTS1.2/TabsSample/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b4f9aafd486609e20cb1aa0832b1788f404453d6 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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.TabsSample", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/code/ArkTS1.2/TabsSample/AppScope/resources/base/element/string.json b/code/ArkTS1.2/TabsSample/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..ca3844b3e0e22c672df8a993e83c11dc09de5ebc --- /dev/null +++ b/code/ArkTS1.2/TabsSample/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "TabsSample" + } + ] +} diff --git a/code/ArkTS1.2/TabsSample/AppScope/resources/base/media/app_icon.png b/code/ArkTS1.2/TabsSample/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/AppScope/resources/base/media/app_icon.png differ diff --git a/code/ArkTS1.2/TabsSample/README.md b/code/ArkTS1.2/TabsSample/README.md new file mode 100644 index 0000000000000000000000000000000000000000..aac61c9e88baf36ebbc5085216fca05231e04f85 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/README.md @@ -0,0 +1,101 @@ +# 主页Tabs嵌套场景 + +### 介绍 + +1. 主页嵌套场景,使用tabContent嵌套; +2. 实现预加载; +3. 主页使用自定义tabbar; +4. 主页数据加载使用网络数据,轮播图片和列表信息; + +### 效果预览 + +效果如下所示: + +|主界面|主页瀑布流实现案例|折叠面板案例|自定义TabBar页签案例|TabContent内容可以在TabBar上显示并响应滑动事件案例| +|--------------------------------|--------------------------------|--------------------------------|--------------------------------|--------------------------------| +|![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. 在主界面,点击蓝色按钮"折叠面板案例"。 + * 进入性能文章标签页面。 + * 点击多层级列表,展开子列表。 +3. 在主界面,点击蓝色按钮"自定义TabBar页签案例"。 + * 依次点击TabBar页面,除了视频图标外,其余图标往上移动一小段距离。 +4. 在主界面,点击蓝色按钮"TabContent内容可以在TabBar上显示并响应滑动事件案例"。 + * 点击播放按钮进行视频播放,按住进度条按钮和进度条下方区域可以拖动进度条,更改视频播放进度。 + +### 工程目录 + +``` +entry/src/main/ets/ +|---constants +| |---constants.ets +|---model +| |---collapsemenu +| | |---ArticleNode.ets +| | |---BasicDataSource.ets +| | |---MockData.ets +| | |---MockXrData.ets +| | |---TreeNode.ets +| |---functionalScenes +| | |---SceneModuleDatas.ets +| | |---SceneModuleInfo.ets +| | |---TabsData.ets +| | |---WaterFlowDataSource.ets +| |---constantsData.ets +|---pages +| |---collapsemenu +| | |---CollapseMenuSection.ets +| | |---Concent.ets +| |---functionalScenes +| | |---FunctionalScenes.ets +| |---tabBar +| | |---TabBar.ets +| |---tabContentOverFlow +| | |---TabContentOverFlow.ets +| |---Index.ets +``` + +### 具体实现 + +* Example1(主页瀑布流案例),源码参考:[Example1](entry/src/main/ets/pages/functionalScenes/FunctionalScenes.ets) + * 构造懒加载数据源类型。 + * 通过LazyForEach循环构造列表数据。 +* Example2(折叠面板案例),源码参考:[Example2](entry/src/main/ets/pages/collapsemenu/CollapseMenuSection.ets) + * 构造懒加载数据源类型。 + * 使用LazyForEach构造列表数据。 + * 通过点击事件更改expand的值,调用updateData方法通知监听器重新渲染页面,从而实现展开与折叠效果。 +* Example3(自定义TabBar页签案例),源码参考:[Example3](entry/src/main/ets/pages/tabBar/TabBar.ets) + * 创建自定义组件做为TabBar的内容区。 +* Example4(TabContent内容可以在TabBar上显示并响应滑动事件案例),源码参考:[Example4](entry/src/main/ets/pages/tabContentOverFlow/TabContentOverFlow.ets) + * TabContent加载Video组件。 + * 使用自定义进度条并添加PanGesture手势,实现在自定义TabBar上拖动进度条更改视频播放进度的功能。 + +### 相关权限 + +无 + +### 依赖 + +无 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:Phone; +2. 本示例为Stage模型,支持API20版本SDK,SDK版本号(API Version 20),镜像版本号(6.0.0.31)。 +3. 本示例需要使用DevEco Studio 版本号(6.0.0.6)版本才可编译运行。 + +### 下载 + +如需单独下载本工程,执行如下命令: + +``` +git init +git config core.sparsecheckout true +echo code/ArkTS1.2/TabsSample/ > .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/TabsSample/build-profile.json5 b/code/ArkTS1.2/TabsSample/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c83260a8d4a7c41693901753e0c0ea562824569c --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/code-linter.json5 b/code/ArkTS1.2/TabsSample/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..87b3919d419c09728067f1b545b7e2d5116adc07 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/entry/.gitignore b/code/ArkTS1.2/TabsSample/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/entry/build-profile.json5 b/code/ArkTS1.2/TabsSample/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..36f9e65afb2abbbbdda625e86543807eee16240c --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/entry/hvigorfile.ts b/code/ArkTS1.2/TabsSample/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..8f830cdfd5bfdd8bde92ebfc27fc0562423dca3d --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/entry/obfuscation-rules.txt b/code/ArkTS1.2/TabsSample/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/entry/oh-package.json5 b/code/ArkTS1.2/TabsSample/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..39ab3f901494a87d5ab258dfaa9e6882de1f5166 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/entry/src/main/ets/constants/Constants.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/constants/Constants.ets new file mode 100644 index 0000000000000000000000000000000000000000..a57991e01895fd1b59f274a58b93f2b1864d82cb --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/constants/Constants.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export class Constants { + // 普通面板 + static readonly ORDINARY_MENU: number = 1; + // 折叠面板 + static readonly COLLAPSE_MENU: number = 2; +} \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/entryability/EntryAbility.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..77793a620ea74c84912444a93830b079897fce4b --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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' + +class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', 'EntryAbility onCreate'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + hilog.info(0x0000, 'testTag', 'EntryAbility onWindowStageCreate'); + try { + // windowStage.loadContent('pages/AnimateTo', (err: BusinessError): void => { + windowStage.loadContent('pages/Index', (err: BusinessError): void => { + hilog.info(0x0000, 'testTag', 'loadContent entering'); + if (err.code) { + hilog.info(0x0000, 'testTag', 'loadContent error'); + return; + } + hilog.info(0x0000, 'testTag', 'loadContent ok'); + }); + } catch (e: Error) { + hilog.info(0x0000, 'testTag', 'loadContent catch error:-----------' + e.message); + } + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/ArticleNode.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/ArticleNode.ets new file mode 100644 index 0000000000000000000000000000000000000000..52f0951e0e4e5b6bc712087db418971765d523c8 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/ArticleNode.ets @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * 数据类型(开发者可以自行扩展数据属性) + * + * @param {number} type - 数据类型 + * @param {string} title - 数据标题 + * @param {string} url - 文章地址 + * @param {ArticleNode[]} children - 子数据列表 + */ + +export class ArticleNode { + public type: number = 0 + public title: string = '' + public url?: string = '' + public children?:ArticleNode[] = [] +} diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/BasicDataSource.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/BasicDataSource.ets new file mode 100644 index 0000000000000000000000000000000000000000..d476f8508f63f07ea16ffd288e032654c970f274 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/BasicDataSource.ets @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DataChangeListener, IDataSource } from '@ohos.arkui.component' + +/** + * IDataSource处理数据监听的基本实现 + */ +export abstract class BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + // 获取数组长度 + public abstract totalCount(): number; + public abstract getData(index: number): T; + // 为LazyForEach组件向其数据源处添加listener监听 + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + // 为对应的LazyForEach组件在数据源处去除listener监听 + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + // 通知LazyForEach组件需要重载所有子组件 + notifyDataReload(): void { + this.listeners.forEach((listener: DataChangeListener) => { + listener.onDataReloaded(); + }); + } + // 通知LazyForEach组件需要在index对应索引处添加子组件 + notifyDataAdd(index: number): void { + this.listeners.forEach((listener: DataChangeListener) => { + listener.onDataAdd(index); + }) + } + // 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件 + notifyDataChange(index: number): void { + this.listeners.forEach((listener: DataChangeListener) => { + listener.onDataChange(index); + }) + } + // 通知LazyForEach组件需要在index对应索引处删除该子组件 + notifyDataDelete(index: number): void { + this.listeners.forEach((listener: DataChangeListener) => { + listener.onDataDelete(index); + }) + } +} + +export class ArticleSource extends BasicDataSource { + public articleData: Array = []; + public constructor(data: T[] = []) { + super(); + this.pushData(data); + } + // 获取数组长度 + public totalCount(): number { + return this.articleData.length; + } + // 获取指定索引数据 + public getData(index: number): T { + return this.articleData[index]; + } + // 插入单个数据 + public addData(index: number, data: T): void { + this.articleData.splice(index, 0, data); + this.notifyDataAdd(index); + } + public updateData(index: number, data: T): void { + this.articleData.splice(index, 1, data); + this.notifyDataChange(index); + } + // 添加数据 + public pushData(data: T[]): void { + data.forEach((item: T) => { + this.articleData.push(item); + this.notifyDataAdd(this.articleData.length - 1); + }) + } +} diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/MockData.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/MockData.ets new file mode 100644 index 0000000000000000000000000000000000000000..dea2f9765613fa52c1002bd316181132e238019c --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/MockData.ets @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **/ +import { ArticleNode } from './ArticleNode'; + +export const ARTICLE_DATA: ArticleNode[] = [ + { + type: 1, + title: '应用开发性能优化入门引导', + url: 'README.md', + }, + { + type: 1, + title: '性能优化实操宝典', + url: 'performance-optimization-practical-guidance.md', + }, + { + type: 2, + title: 'ArkTS高性能编程', + children: [ + { + type: 1, + title: '高性能编程规范', + url: 'high-performance-programming.md' + }, + { + type: 1, + title: '高效并发编程', + url: 'efficient-concurrent-programming.md' + }, + { + type: 1, + title: 'N-API高效开发指导', + url: 'develop-Native-modules-using-NAPI-safely-and-efficiently.md' + }, + { + type: 1, + title: '多线程能力场景化', + url: 'multi_thread_capability.md' + }, + { + type: 1, + title: '利用native的方式实现跨线程调用', + url: 'native-threads-call-js.md' + }, + { + type: 1, + title: '避免开发过程中的冗余操作', + url: 'avoiding-redundant-operations.md' + } + ] + }, + { + type: 2, + title: '减少卡顿丢帧', + children: [ + { + type: 1, + title: '正确使用LazyForEach优化', + url: 'lazyforeach_optimization.md' + }, + { + type: 1, + title: '组件复用使用指导', + url: 'component-recycle.md' + }, + { + type: 1, + title: '组件复用四板斧', + url: 'component_recycle_case.md' + }, + { + type: 1, + title: '组件复用总览', + url: 'component-reuse-overview.md' + }, + { + type: 1, + title: 'WaterFlow高性能开发指导', + url: 'waterflow_optimization.md' + }, + { + type: 1, + title: 'Swiper高性能开发指导', + url: 'swiper_optimization.md' + }, + { + type: 1, + title: '合理进行状态管理', + url: 'proper_state_management.md' + }, + { + type: 1, + title: '精准控制组件的更新范围', + url: 'precisely-control-render-scope.md' + }, + { + type: 1, + title: '合理使用renderGroup', + url: 'reasonable-using-renderGroup.md' + }, + { + type: 1, + title: '合理使用多线程共享内存', + url: 'thread_memory_shared.md' + }, + { + type: 1, + title: 'Grid高性能开发指导', + url: 'grid_optimization.md' + }, + { + type: 1, + title: '状态管理优秀实践', + url: 'arkts-state-management-best-practices.md' + }, + { + type: 1, + title: '合理使用renderGroup', + url: 'reasonable-using-renderGroup.md' + }, + { + type: 1, + title: '合理处理高负载组件的渲染', + url: 'reasonably-dispose-highly-loaded-component-render.md' + }, + { + type: 1, + title: '合理使用自定义组件冻结功能', + url: 'custom_component_freeze.md' + }, + { + type: 1, + title: '避免在滑动场景的高频回调接口中处理耗时操作', + url: 'avoid_high_frequency_callback_execute_lengthy_operation.md' + }, + { + type: 1, + title: '合理使用renderGroup', + url: 'reasonable-using-renderGroup.md' + }, + { + type: 1, + title: '避免在主线程中执行耗时操作', + url: 'avoid_time_consuming_operations_in_mainthread.md' + }, + { + type: 1, + title: '避免在主线程中执行耗时操作', + url: 'avoid_time_consuming_operations_in_mainthread.md' + }, + { + type: 1, + title: '合理使用系统接口', + url: 'reasonable_using_system_interfaces.md' + } + ] + }, + { + type: 2, + title: '提升应用启动和响应速度', + children: [ + { + type: 1, + title: '提升应用冷启动速度', + url: 'improve-application-cold-start-speed.md' + }, + { + type: 1, + title: '提升应用响应速度', + url: 'improve-application-response.md' + }, + { + type: 1, + title: 'Flex布局性能提升使用指导', + url: 'flex-development-performance-boost.md' + }, + { + type: 1, + title: '优化布局性能', + url: 'reduce-view-nesting-levels.md' + }, + { + type: 1, + title: '合理选择条件渲染和显隐控制', + url: 'proper-choice-between-if-and-visibility.md' + }, + { + type: 1, + title: '合理使用IPC通信', + url: 'reasonable-using-ipc.md' + }, + { + type: 1, + title: '合理进行状态管理', + url: 'reasonable-using-ipc.md' + }, + { + type: 1, + title: '文件上传下载性能提升指导', + url: 'improve-file-upload-and-download-performance.md' + }, + { + type: 1, + title: '减少首帧绘制时的冗余操作', + url: 'reduce-redundant-operations-when-render-first-frame.md' + }, + { + type: 1, + title: '合理使用多线程共享内存', + url: 'thread_memory_shared.md' + }, + { + type: 1, + title: '动效能力实践', + url: 'animation_practice.md' + }, + { + type: 1, + title: '性能提升的其他方法', + url: 'arkts-performance-improvement-recommendation.md' + }, + { + type: 1, + title: '合理使用renderGroup', + url: 'reasonable-using-renderGroup.md' + }, + { + type: 1, + title: '运行时动态加载页面提升性能', + url: 'performance-dynamic-import.md' + }, + { + type: 1, + title: '合理运行后台任务', + url: 'reasonable-running-backgroundTask.md' + }, + { + type: 1, + title: 'Web组件开发性能提升指导', + url: 'performance-web-import.md' + }, + { + type: 1, + title: '使用同层渲染在Web上渲染原生组件', + url: 'webview-render-app-components.md' + }, + { + type: 1, + title: '全局自定义组件复用实现', + url: 'node_custom_component_reusable_pool.md' + } + ] + }, + { + type: 2, + title: '性能工具', + children: [ + { + type: 1, + title: '性能分析工具CPU Profiler', + url: 'application-performance-analysis.md' + }, + { + type: 1, + title: '页面布局检查器ArkUI Inspector', + url: 'arkUI-inspector.md' + }, + { + type: 1, + title: '内存分析器Allocation Profiler', + url: 'profiler-allocation.md' + }, + { + type: 1, + title: '帧率分析工具 Frame Profiler', + url: 'profiler-frame.md' + }, + { + type: 1, + title: '启动分析工具Launch Profiler', + url: 'profiler-launch.md' + }, + { + type: 1, + title: '内存快照Snapshot Profiler', + url: 'profiler-snapshot.md' + }, + { + type: 1, + title: '耗时分析器Time Profiler', + url: 'profiler-time.md' + }, + { + type: 1, + title: '性能测试工具SmartPerf Editor', + url: 'smartperf-editor.md' + }, + { + type: 1, + title: '性能优化工具HiDumper', + url: 'performance-optimization-using-hidumper.md' + }, + { + type: 1, + title: '性能优化工具SmartPerf-Host', + url: 'performance-optimization-using-smartperf-host.md' + }, + { + type: 1, + title: '常用trace使用指导', + url: 'common-trace-using-instructions.md' + }, + { + type: 1, + title: '性能提升的其他方法', + url: 'arkts-performance-improvement-recommendation.md' + }, + { + type: 1, + title: '合理使用renderGroup', + url: 'reasonable-using-renderGroup.md' + }, + { + type: 1, + title: '状态变量组件定位工具实践', + url:'state_variable_dfx_pratice.md' + }, + { + type: 1, + title: '应用滑动场景帧率问题分析实践', + url: 'long-frame-optimization.md' + }, + { + type: 1, + title: 'Web性能问题分析案例', + url: 'web-analyse.md' + }, + { + type: 1, + title: '时延类性能问题分析实践', + url: 'delay_related_performance.md' + } + ] + } +] \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/MockXrData.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/MockXrData.ets new file mode 100644 index 0000000000000000000000000000000000000000..f8c2e0270df180cf4fcd14a12a61808614741048 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/MockXrData.ets @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **/ +import { TreeNode } from './TreeNode'; + +export const ARTICLE_DATA1: TreeNode[] = [ + { + expand: true, + type: 1, + title: '应用开发性能优化入门引导', + url: 'README.md', + }, + { + expand: false, + type: 1, + title: '性能优化实操宝典', + url: 'performance-optimization-practical-guidance.md', + }, + { + expand: false, + type: 2, + title: 'ArkTS高性能编程', + children: [ + { + expand: false, + type: 1, + title: '高性能编程规范', + url: 'high-performance-programming.md' + }, + { + expand: false, + type: 1, + title: '高效并发编程', + url: 'efficient-concurrent-programming.md' + }, + { + expand: false, + type: 1, + title: '避免开发过程中的冗余操作', + url: 'avoiding-redundant-operations.md' + } + ] + }, + { + expand: false, + type: 2, + title: '减少卡顿丢帧', + children: [ + { + expand: false, + type: 1, + title: '正确使用LazyForEach优化', + url: 'lazyforeach_optimization.md' + }, + { + expand: false, + type: 1, + title: '组件复用使用指导', + url: 'component-recycle.md' + } + ] + }, + { + expand: false, + type: 2, + title: '提升应用启动和响应速度', + children: [ + { + expand: false, + type: 1, + title: '提升应用冷启动速度', + url: 'improve-application-cold-start-speed.md' + }, + { + expand: false, + type: 1, + title: '提升应用响应速度', + url: 'improve-application-response.md' + }, + { + expand: false, + type: 1, + title: 'Flex布局性能提升使用指导', + url: 'flex-development-performance-boost.md' + } + ] + }, + { + expand: false, + type: 2, + title: '性能工具', + children: [ + { + expand: false, + type: 1, + title: '性能分析工具CPU Profiler', + url: 'application-performance-analysis.md' + }, + { + expand: false, + type: 1, + title: '页面布局检查器ArkUI Inspector', + url: 'arkUI-inspector.md' + }, + { + expand: false, + type: 1, + title: '内存分析器Allocation Profiler', + url: 'profiler-allocation.md' + }, + { + expand: false, + type: 1, + title: '性能测试工具SmartPerf Editor', + url: 'smartperf-editor.md' + } + ] + } + +] \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/TreeNode.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/TreeNode.ets new file mode 100644 index 0000000000000000000000000000000000000000..06b43608280d04a1f16c6929b23833d41fd0869f --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/collapsemenu/TreeNode.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Observed } from '@ohos.arkui.stateManagement' +@Observed +export class TreeNode { + public expand: boolean = false; + public type: number | string | ESObject = 0 + public title: string = '' + public url?: string = '' + public children?: TreeNode[] = []; +} \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/constantsData.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/constantsData.ets new file mode 100644 index 0000000000000000000000000000000000000000..d7834ed815d9581430f7a4c7b6101e2d4905510f --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/constantsData.ets @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TreeNode } from './collapsemenu/TreeNode'; +export const STYLE_CONFIGURATION: Record = { + 'TAB_BAR_HEIGHT': 48, // 页签高度 + 'ICON_SIZE': 16, // 图标尺寸 + 'TAB_BAR_CONTENT_GUTTER': 6, // 页签内元素间距 + 'TAB_BAR_ITEM_GUTTER': 6, // 页签间距 + 'SEPARATOR_STROKE_WIDTH': 2, // 分割线宽度 + 'CONTENT_GUTTER_M': 12, // 元素间距 + 'CONTENT_GUTTER_S': 8, // 元素间距 + 'GRID_HEIGHT': 170, // 快捷方式高度 + 'GRID_MARGIN': 48, // 快捷方式外边距 + 'TAB_SHEET_PADDING': 6, // 页签内边距 + 'IMAGE_SIZE': 56, // 图片尺寸 + 'IMAGE_RADIUS': 32, // 图片圆角 + 'TEXT_HEIGHT': 12, // 文本高度 + 'TEXT_WIDTH': 48, // 文本宽度 + 'SEARCH_HEIGHT': 28, // 工具栏搜索框高度 + 'BIG_ICON_SIZE': 30, // 添加和删除按钮的尺寸 + 'BIG_ICON_PADDING': 7, // 添加和删除按钮的padding值 + 'IMAGE_MARGIN':12 // 当添加到第六个标签删除按钮的margin值 +} + +export const ARTICLENODE_DATAS: TreeNode[] = [ + { + expand: true, + type: 2, + title: '第一章:基础入门', + url: 'video1', + children: [ + { + expand: true, + type: 2, + title: '1.1 介绍', + url: 'video1-1', + children: [] + }, + { + expand: true, + type: 2, + title: '1.2 安装环境', + url: 'video1-2', + children: [] + } + ] + }, + { + expand: false, + type: 1, + title: '第二章:进阶技巧', + url: 'video2', + children: [ + { + expand: false, + type: 2, + title: '2.1 性能优化', + url: 'video2-1', + children: [] + } + ] + } +]; + diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/SceneModuleDatas.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/SceneModuleDatas.ets new file mode 100644 index 0000000000000000000000000000000000000000..43afd5dd98df8a125d81dd07e6e49d35ea006ee8 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/SceneModuleDatas.ets @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { SceneModuleInfo } from './SceneModuleInfo'; +import { $r } from '@ohos.arkui.component' +export const SCENE_MODULE_LIST: SceneModuleInfo[] = [ + new SceneModuleInfo( + $r('app.media.backgroundblur_my_select'), + '应用开发性能优化入门引导', + 'performance/PerformanceIntroView', + '性能优化', + 1, + 3, + $r('app.media.backgroundblur_my_select'), + '', + 'README.md' + ), + new SceneModuleInfo( + $r('app.media.backgroundblur_my_select'), + '性能优化实操宝典', + 'performance/PerformancePracticeView', + '性能优化', + 2, + 4, + $r('app.media.backgroundblur_my_select'), + '', + 'performance-optimization-practical-guidance.md' + ), + new SceneModuleInfo( + $r('app.media.backgroundblur_my_select'), + 'UI 框架基础使用', + 'uiframework/UIFrameworkBasicsView', + '界面开发', + 3, + 2, + $r('app.media.backgroundblur_my_select'), + '', + 'ui-framework.md' + ), + new SceneModuleInfo( + $r('app.media.backgroundblur_my_select'), + '动效开发实战', + 'animation/AnimationPracticeView', + '界面开发', + 4, + 4, + $r('app.media.backgroundblur_my_select'), + '', + 'animation-guide.md' + ), + new SceneModuleInfo( + $r('app.media.backgroundblur_my_select'), + '数据存储与文件操作', + 'storage/StorageModuleView', + '基础能力', + 5, + 3, + $r('app.media.backgroundblur_my_select'), + '', + 'storage-and-file.md' + ), + new SceneModuleInfo( + $r('app.media.backgroundblur_my_select'), + '路由与模块解耦', + 'router/RouterNavigationView', + '路由跳转', + 6, + 3, + $r('app.media.backgroundblur_my_select'), + '', + 'router-guide.md' + ) +]; diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/SceneModuleInfo.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/SceneModuleInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..3868984cc5740a72f2593e119d1fe44ea4266887 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/SceneModuleInfo.ets @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ResourceStr } from '@ohos.arkui.component' +/** + * 首页瀑布流列表信息 + */ +export class SceneModuleInfo { + // 首页列表图片 + public imageSrc: ResourceStr; + // 首页列表名称 + public name: string; + // 路由信息,自动生成路由时,在自定义装饰器中AppRouter中配置的参数,使用新版本自动路由时需要添加此参数,用于动态路由的跳转。 + // 使用规则:模块名/需要加载的自定义组件名,如addressexchange/AddressExchangeView + public appUri: string; + // 路由传参数据 + public param: string; + // 难度星级 + public ratingNumber: number; + // 分类 + public category: string; + // 序号 + public serialNumber: number; + // 首页轮播静态图 + public swiperImage: ResourceStr; + // 案例README地址 + public helperUrl: string; + + constructor(imageSrc: ResourceStr, name: string, appUri: string, category: string, serialNumber: number, + ratingNumber?: number, swiperImage?: ResourceStr, param?: string, helperUrl?: string) { + this.imageSrc = imageSrc; + this.name = name; + this.appUri = appUri; + this.param = param === undefined ? '' : param; + this.ratingNumber = ratingNumber === undefined ? 2 : ratingNumber; + this.category = category; + this.serialNumber = serialNumber; + this.swiperImage = swiperImage === undefined ? '' : swiperImage; + this.helperUrl = helperUrl === undefined ? '' : helperUrl; + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/TabsData.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/TabsData.ets new file mode 100644 index 0000000000000000000000000000000000000000..0f0caebe25311f1c2b98fa1e9173a56a9e7208e3 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/TabsData.ets @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DataChangeListener, IDataSource } from '@ohos.arkui.component' + +/** + * 首页tabBar信息 + */ +export class TabDataModel { + // tabId用户切换tabContent + public id: number = 0; + // tab类别 + public navData: string | undefined = undefined; + + constructor(id: number, navData: string) { + this.navData = navData; + this.id = id; + } +} + +export const TAB_DATA: Array = [ + new TabDataModel(0, '全部'), + new TabDataModel(1, 'Native'), + new TabDataModel(2, '动效'), + new TabDataModel(3, '三方库'), + new TabDataModel(4, 'UI布局'), + new TabDataModel(5, '性能示例'), + new TabDataModel(6, '其他'), + new TabDataModel(7, '性能文章') +] + +// Basic implementation of IDataSource to handle data listener +class BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: TabDataModel[] = []; + + public totalCount(): number { + return 0; + } + + public getData(index: number): TabDataModel { + return this.originDataArray[index]; + } + + /** + * 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听 + */ + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + console.info('add listener'); + this.listeners.push(listener); + } + } + + /** + * 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听 + */ + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + console.info('remove listener'); + this.listeners.splice(pos, 1); + } + } + + /** + * 通知LazyForEach组件需要重载所有子组件 + */ + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + /** + * 通知LazyForEach组件需要在index对应索引处添加子组件 + */ + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + /** + * 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件 + */ + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + /** + * 通知LazyForEach组件需要在index对应索引处删除该子组件 + */ + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } +} + +/** + * 实现TabDataSource接口的对象,用于tabs加载数据 + */ +export class TabDataSource extends BasicDataSource { + private dataArray: TabDataModel[] = []; + + /** + * 获取数据总数 + * @returns + */ + public totalCount(): number { + return this.dataArray.length; + } + + /** + * 获取索引对应的数据 + * @param index 数组索引 + * @returns + */ + public getData(index: number): TabDataModel { + return this.dataArray[index]; + } + + /** + * 在指定索引位置增加一个元素 + * @param index + */ + public addData(index: number, data: TabDataModel): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + /** + * 在数据尾部增加一个元素 + */ + public pushData(data: TabDataModel): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/WaterFlowDataSource.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/WaterFlowDataSource.ets new file mode 100644 index 0000000000000000000000000000000000000000..8b5e3a4c7e86a888ddb018992b563ca863417af6 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/model/functionalScenes/WaterFlowDataSource.ets @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SceneModuleInfo } from './SceneModuleInfo' +import { DataChangeListener, IDataSource } from '@ohos.arkui.component' +/** + * 实现IDataSource接口的对象,用于瀑布流组件加载数据 + */ +export class WaterFlowDataSource implements IDataSource { + private dataArray: SceneModuleInfo[] = []; + private listeners: DataChangeListener[] = []; + + constructor(dataArray: SceneModuleInfo[]) { + for (let i = 0; i < dataArray.length; i++) { + this.dataArray.push(dataArray[i]); + } + } + + /** + * 获取索引对应的数据 + * @param index 数组索引 + * @returns + */ + public getData(index: number): SceneModuleInfo { + return this.dataArray[index]; + } + + /** + * 通知控制器数据重新加载 + */ + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + /** + * 通知控制器数据增加 + * @param index 数组索引 + */ + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + /** + * 通知控制器数据变化 + * @param index 数组索引 + */ + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + /** + * 通知控制器数据删除 + * @param index 数组索引 + */ + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + /** + * 通知控制器数据位置变化 + * @param from 起始位置 + * @param to 最终位置 + */ + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } + + /** + * 获取数据总数 + * @returns + */ + public totalCount(): number { + return this.dataArray.length; + } + + /** + * 注册改变数据的控制器 + * @param listener 数据控制器 + */ + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + /** + * 注销改变数据的控制器 + * @param listener 数据控制器 + */ + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener) + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + + /** + * 增加数据 + */ + public add1stItem(): void { + this.dataArray.splice(0, 0, this.dataArray[this.dataArray.length]); + this.notifyDataAdd(0); + } + + /** + * 在数据尾部增加一个元素 + */ + public addLastItem(): void { + this.dataArray.splice(this.dataArray.length, 0, this.dataArray[this.dataArray.length]); + this.notifyDataAdd(this.dataArray.length - 1); + } + + /** + * 在指定索引位置增加一个元素 + * @param index + */ + public addItem(index: number): void { + this.dataArray.splice(index, 0, this.dataArray[this.dataArray.length]); + this.notifyDataAdd(index); + } + + /** + * 删除第一个元素 + */ + public delete1stItem(): void { + this.dataArray.splice(0, 1); + this.notifyDataDelete(0); + } + + /** + * 删除第二个元素 + */ + public delete2ndItem(): void { + this.dataArray.splice(1, 1); + this.notifyDataDelete(1); + } + + /** + * 删除最后一个元素 + */ + public deleteLastItem(): void { + this.dataArray.splice(-1, 1); + this.notifyDataDelete(this.dataArray.length); + } + + /** + * 重新加载数据 + */ + public reload(): void { + this.notifyDataReload(); + } + + /** + * 改变数组数据 + * @param data:新数组 + */ + public modifyAllData(data: SceneModuleInfo[]): void { + this.dataArray = data; + this.notifyDataReload(); + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/Index.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..3d1cb64296edb759c116cd51f64da9c8c49442ac --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { memo, __memo_context_type, __memo_id_type } from '@ohos.arkui.stateManagement'; // should be insert by ui-plugins +import { Margin, Column, Component, Entry, UserView } from '@ohos.arkui.component'; // TextAttribute should be insert by ui-plugins +import { Text, List, ListItem, TextAttribute, Column, Component, Button, ButtonAttribute, ClickEvent, UserView, $r,FlexAlign, + Image, Margin, Blank, Row, Builder, Alignment, ForEach, Padding, Color, Divider, Tabs, TabContent, BuilderParam, JSON, + LazyForEach, ListItemGroup, Entry, Canvas, CanvasRenderingContext2D, RenderingContextSettings +} from '@ohos.arkui.component'; // TextAttribute should be insert by ui-plugins +import hilog from '@ohos.hilog'; +import camera from '@ohos.multimedia.camera'; +import { UIContext } from '@ohos.arkui.UIContext' + +@Entry +@Component +struct MyStateSample { + build() { + Column(undefined) { + Button($r('app.string.background_blur_discover')) + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().pushUrl({url: 'pages/collapsemenu/CollapseMenuSection'}) + }) + .width('80%') + Button($r('app.string.background_blur_hot')) + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().pushUrl({url: 'pages/functionalScenes/FunctionalScenes'}) + }) + .width('80%') + .margin({top: 20} as Margin) + Button($r('app.string.custom_tab_bar')) + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().pushUrl({url: 'pages/tabBar/TabBar'}) + }) + .width('80%') + .margin({top: 20} as Margin) + Button($r('app.string.custom_tab_Content')) + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().pushUrl({url: 'pages/tabContentOverFlow/TabContentOverFlow'}) + }) + .width('80%') + .margin({top: 20} as Margin) + } + .justifyContent(FlexAlign.Center) + .width('100%') + } +} + +export class ComExampleTrivialApplication extends UserView { + getBuilder() { + let wrapper = @memo () => { + MyStateSample(undefined) + } + return wrapper + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/collapsemenu/CollapseMenuSection.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/collapsemenu/CollapseMenuSection.ets new file mode 100644 index 0000000000000000000000000000000000000000..5e42d57efa3fd69a09a11167260e0791dc21c4a7 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/collapsemenu/CollapseMenuSection.ets @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **/ + +import { Constants } from '../../constants/Constants'; +import { ArticleSource } from '../../model/collapsemenu/BasicDataSource'; +import { TreeNode } from '../../model/collapsemenu/TreeNode'; +import { Text, List, ListItem, Column, LazyForEach, Button, Image, Row, ForEach, + ButtonAttribute, ClickEvent, Component, BuilderParam, Padding, $r, + BarState, NestedScrollOptions, NestedScrollMode, Color, JSON, Alignment, + ListItemGroup, Divider, Builder, Margin, Blank, Entry + } from '@ohos.arkui.component' +import { Provide, State, ObjectLink, Consume } from '@ohos.arkui.stateManagement' +import { ARTICLENODE_DATAS } from '../../model/constantsData' +import { ARTICLE_DATA1 } from '../../model/collapsemenu/MockXrData'; +import hilog from '@ohos.hilog' +import { UIContext } from '@ohos.arkui.UIContext' + +/** + * 功能描述: + * 1. 进入页面,呈现面板列表,点击普通面板,跳转到对应文章的网页。 + * 2. 点击折叠面板,面板展开,再次点击,面板收起。 + * + * 实现原理: + * 1. 使用List组件遍历折叠面板数据,如果数据含有children数据,使用ListGroup进行二次遍历渲染。(当前场景只支持嵌套层次为两级,多层级待扩展) + * 2. 点击ListGroup的header组件以及visibility来控制子列表的显示和隐藏。 + * + * @param {ArticleNode[]} articleNodes - 折叠面板列表数据 + * @param {(articleNode: ArticleNode)=>void} articleItemBuilder - 列表项视图 + * @param {(articleNode: ArticleNode, isExpand:boolean)=>void} articleHeaderBuilder - 列表头部视图 + */ + +@Entry +@Component +export struct CollapseMenuSection { + // 折叠面板列表数据 + articleNodes: TreeNode[] = ARTICLE_DATA1; + // 懒加载数据 + articleSource: ArticleSource = new ArticleSource(this.articleNodes); + + build() { + Column() { + Row() { + Text($r('app.string.custom_return')) + } + .margin(3) + .width('100%') + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().back(); + }) + List({ space: 10 }) { + LazyForEach(this.articleSource, (item: TreeNode, index: number) => { + if (item.children?.length) { + ListItemGroup() { + ListItem() { + this.articleHeaderBuilder(item) + } + .onClick((e: ClickEvent) => { + item.expand = !item.expand; + this.articleSource.updateData(index, item); + }) + + if (item.expand && item.children) { + this.treeBuilder(item.children as TreeNode[], 1, index) + } + } + .width('100%') + .borderRadius(12) + .backgroundColor(Color.White) + .padding({ + left: 12, + right: 12, + bottom: 4, + top: 4 + } as Padding) + .align(Alignment.TopStart) + + } else { + ListItem() { + this.articleItemBuilder(item); + } + .width('100%') + .borderRadius(12) + .backgroundColor(Color.White) + .padding({ + left: 12, + right: 12, + bottom: 4, + top: 4 + } as Padding) + .align(Alignment.TopStart) + } + }, (itemj: TreeNode ,index: number ) => {return itemj.title + itemj.expand + index}) + } + .width('100%') + .padding({ + left: 12, + right: 12, + bottom: 12 + } as Padding) + .backgroundColor('#F3F3F3') + } +} + + @Builder + articleItemBuilder(articleNode: TreeNode) { + Column() { + Row() { + Text(articleNode.title) + .fontSize($r('app.integer.collapse_menu_text_font_size')) + .layoutWeight(1) + .align(Alignment.Start) + .fontFamily('HarmonyHeiTi-Medium') + .fontColor($r('app.color.font_color_dark')) + Blank() + } + .height(48) + .width('100%') + .onClick((e: ClickEvent) => { + if (articleNode.url) { + + } + }) + } + } + + @Builder + articleHeaderBuilder(articleNode: TreeNode) { + Row() { + Text(articleNode.title) + .fontSize($r('app.integer.collapse_menu_text_font_size')) + .fontFamily('HarmonyHeiTi-Medium') + .fontColor($r('app.color.font_color_dark')) + Blank() + Image(articleNode.expand ? $r('app.media.ic_down_arrow') : $r('app.media.ic_right_arrow')) + .width(articleNode.expand ? 24 : + 12) + .height(articleNode.expand ? 12 : + 24) + .margin({ right: 6} as Margin) + } + .height(56) + .width('100%') + } + + @Builder + treeBuilder(articleNodes: TreeNode[], count: number, parentIndex: number) { + ForEach(articleNodes, (articleNode: TreeNode, index: number) => { + this.createBuilder(articleNode, count, parentIndex) + if (articleNode.expand === true && articleNode?.children?.length) { + this.treeBuilder(articleNode.children as TreeNode[], count + 1, index) + } + }) + } + + @Builder + createBuilder(articleNode: TreeNode, count: number, parentIndex: number) { + ArticleItem({ + articleNode: articleNode, + count, + articleGroupIndex: parentIndex + }) + } + +} + + +@Component +struct ArticleItem { + articleNode: TreeNode = {} as TreeNode; + count: number = 0; + @State articleSource: ArticleSource = {} as ArticleSource; + articleGroupIndex: number = -1; + build() { + ListItem() { + Column() { + Column() { + if (this.articleNode.type === Constants.COLLAPSE_MENU) { + Column() { + this.articleHeaderBuilder({ + expand: this.articleNode.expand, + type: this.articleNode.type, + title: this.articleNode.title, + url: this.articleNode.url, + children: this.articleNode.children, + } as TreeNode) + } + .onClick((e: ClickEvent) => { + + }) + } else { + this.articleItemBuilder(this.articleNode); + } + } + .width('100%') + Divider() + .height(1) + .opacity(0.2) + .color($r('app.color.font_color_dark')) + } + } + } + + @Builder + articleItemBuilder(articleNode: TreeNode) { + Column() { + Row() { + Text(articleNode.title) + .fontSize($r('app.integer.collapse_menu_text_font_size')) + .layoutWeight(1) + .align(Alignment.Start) + .fontFamily('HarmonyHeiTi-Medium') + .fontColor($r('app.color.font_color_dark')) + Blank() + } + .height(48) + .width('100%') + .onClick((e: ClickEvent) => { + if (articleNode.url) { + this.getUIContext().getRouter().pushUrl({url: 'pages/collapsemenu/Concent'}); + } + }) + } + } + + @Builder + articleHeaderBuilder(articleNode: TreeNode) { + Row() { + Text(articleNode.title) + .fontSize($r('app.integer.collapse_menu_text_font_size')) + .fontFamily('HarmonyHeiTi-Medium') + .fontColor($r('app.color.font_color_dark')) + Blank() + Image(articleNode.expand ? $r('app.media.ic_down_arrow') : $r('app.media.ic_right_arrow')) + .width(articleNode.expand ? 24 : + 12) + .height(articleNode.expand ? 12 : + 24) + .margin({ right: 6} as Margin) + } + .height(56) + .width('100%') + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/collapsemenu/Concent.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/collapsemenu/Concent.ets new file mode 100644 index 0000000000000000000000000000000000000000..30b7b4b2aaa2c3a108eeeccc5aefbb9b031a4c46 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/collapsemenu/Concent.ets @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { UIContext } from '@ohos.arkui.UIContext' +import { Text, List, ListItem, TextAttribute, Column, Component, Button, ButtonAttribute, ClickEvent, UserView, $r, + Image, Margin, Blank, Row, Builder, Alignment, ForEach, Padding, Color, Divider, Tabs, TabContent, BuilderParam, JSON, + LazyForEach, ListItemGroup, Entry, Canvas, CanvasRenderingContext2D, RenderingContextSettings,FlexAlign +} from '@ohos.arkui.component'; +@Entry +@Component +struct Concent { + build() { + Column(undefined) { + Row() { + Text($r('app.string.custom_return')) + } + .margin(3) + .width('100%') + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().back(); + }) + Column() { + Text($r('app.string.custom_detail')).fontSize(20) + } + .height('100%') + .width('100%') + .justifyContent(FlexAlign.Center) + .align(Alignment.Center) + } + .margin({ + bottom: 24, + } as Margin) + .height('110%') + .width('100%') + .backgroundColor('#F3F3F3') + } +} diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/functionalScenes/FunctionalScenes.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/functionalScenes/FunctionalScenes.ets new file mode 100644 index 0000000000000000000000000000000000000000..587b1ad1ca4de60589a63bf9c3ed7f30f9301f86 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/functionalScenes/FunctionalScenes.ets @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import promptAction from '@ohos.promptAction'; +import { Text, List, ListItem, Column, Button, Image, Row, Stack,ListItemGroup, Divider, Blank, + Tabs, TabContent, Flex, FlexOptions, Callback, px2vp, ItemAlign, BackgroundBrightnessOptions, + ButtonAttribute, ClickEvent, Component, BuilderParam, Padding, $r, SafeAreaEdge, BackgroundBlurStyleOptions, + BarState, NestedScrollOptions, NestedScrollMode, Color, JSON, Alignment, FlexDirection, BarPosition, + FlexAlign, BlurStyle, LazyForEach, ForEach, Builder, Margin, SafeAreaType, MenuItemOptions, + TabsController, TabsOptions ,StackOptions, ThemeColorMode, AdaptiveColor, ResourceStr, SizeOptions, + Reusable, TextOverflowOptions, ListOptions, LinearGradientOptions, Menu, MenuItem, Axis, BorderRadiuses, + WaterFlow, FlowItem, ImageFit, TextAlign, Scroll, ScrollAlign, Scroller, TextOverflow, ShadowStyle, TabsAnimationEvent, + OnTabsAnimationStartCallback, Rating, RatingOptions, GestureGroup, GestureEvent, GestureMode, TapGesture, $$, + SheetSize, SheetType, ScrollSizeMode, SheetOptions, CustomBuilder, Entry +} from '@ohos.arkui.component' +import { State, StateDecoratedVariable, MutableState, stateOf, AppStorage, + observableProxy,ObjectLink, Observed, Consume, Link, Provide, Watch} from '@ohos.arkui.stateManagement' +import display from '@ohos.display'; +import { SceneModuleInfo } from '../../model/functionalScenes/SceneModuleInfo'; +import { WaterFlowDataSource } from '../../model/functionalScenes/WaterFlowDataSource'; +import { TAB_DATA, TabDataModel } from '../../model/functionalScenes/TabsData'; +import { SCENE_MODULE_LIST } from '../../model/functionalScenes/SceneModuleDatas' +import { CollapseMenuSection } from '../collapsemenu/CollapseMenuSection'; +import { UIContext } from '@ohos.arkui.UIContext' + +/** + * 主页瀑布流列表 + */ +@Entry +@Component +export struct FunctionalScenes { + listData: SceneModuleInfo[] = SCENE_MODULE_LIST; + dataSource: WaterFlowDataSource = new WaterFlowDataSource(this.listData); + @State tabsIndex: number = 0; + tabsController: TabsController = new TabsController(); + private scrollController: Scroller = new Scroller(); + items:number[] = [1,2,3,4,5,6,7,8,9,10] as number[]; + @Builder + tabBuilder(index: number, name: string | undefined) { + Stack() { + Column() { + } + .width(this.tabsIndex === index ? 97 : 71) + .backgroundColor(this.tabsIndex === index ? '#0A59F7' : '#000000') + .opacity(this.tabsIndex === index ? 1 : 0.05) + .height(38) + .borderRadius(21) + Text(name) + .fontSize(14) + .fontColor(this.tabsIndex === index ? Color.White : Color.Black) + .opacity(this.tabsIndex === index ? 1 : 0.8) + .height('100%') + .id('section') + } + .margin(index !== 0 && index !== TAB_DATA.length ? { left: 9 } as Margin : { + left: 0, + right: 0 + } as Margin) + .align(Alignment.Center) + .onClick((e: ClickEvent) => { + this.tabsIndex = index; + this.tabsController.changeIndex(index); + }) + } + + @Builder + tabsMenu() { + Menu() { + ForEach(TAB_DATA, (item: TabDataModel) => { + MenuItem({ content: item.navData } as MenuItemOptions) + .onClick((e: ClickEvent) => { + this.tabsIndex = item.id; + this.tabsController.changeIndex(item.id); + }) + .id('menu_item') + }) + } + } + + /** + * 主页通过瀑布流和LazyForeach加载 + * WaterFlow+LazyForEach详细用法可参考性能范例: + * waterflow_optimization.md/ + */ + build() { + Column() { + Row() { + Text($r('app.string.custom_return')) + } + .margin(3) + .width('100%') + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().back(); + }) + Row() { + Stack() { + List({ scroller: this.scrollController } as ListOptions) { + ForEach(TAB_DATA, (tabItem: TabDataModel) => { + ListItem() { + this.tabBuilder(tabItem.id, tabItem.navData); + } + }) + } + .id('MainList') + .margin({ top: 3 } as Margin) + .height(38) + .listDirection(Axis.Horizontal) + .padding({ right: 46 } as Padding) + .scrollBar(BarState.Off) + Row() { + Row() { + Image($r('app.media.ic_public_more')) + .width(20) + .id('mainPageTabsImage') + } + .bindMenu(this.tabsMenu) + .justifyContent(FlexAlign.Center) + .width(43) + .height(43) + .borderRadius(100) + .backgroundColor('rgba(216, 216, 216, 0)') + .id('menu_button') + } + .linearGradient({ + angle: 90, + colors: [['rgba(241, 241, 241, 0)', 0], ['#F1F3F5', 0.2], ['#F1F3F5', 1]] + } as LinearGradientOptions) + .justifyContent(FlexAlign.End) + .width(60) + .height(43) + } + .alignContent(Alignment.TopEnd) + } + .padding({ + left: 13, + right: 13 + } as Padding) + .margin({ top: 8 } as Margin) + Tabs({ controller: this.tabsController } as TabsOptions) { + ForEach(TAB_DATA, (tabItem: TabDataModel) => { + TabContent() { + if (tabItem.navData === '全部') { + List() { + LazyForEach(this.dataSource, (waterFlowItem: SceneModuleInfo) => { + ListItem(){ + methodPoints({ listData: waterFlowItem }) + } + }, (waterFlowItem: SceneModuleInfo) => JSON.stringify(waterFlowItem)) + } + .nestedScroll({ + scrollForward: NestedScrollMode.PARENT_FIRST, + scrollBackward: NestedScrollMode.SELF_FIRST + } as NestedScrollOptions) + .width('100%') + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .padding({ bottom: $r('app.integer.functional_scenes_water_flow_padding_bottom') } as Padding) + } else { + Column() { + Text(tabItem.navData).fontSize(20) + } + .height('100%') + .width('100%') + .justifyContent(FlexAlign.Center) + .align(Alignment.Center) + } + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .align(Alignment.TopStart) + .alignSelf(ItemAlign.Start) + }) + } + .margin({ top: 8 } as Margin) + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .padding({ + left: 13, + right: 13 + } as Padding) + .barWidth(0) + .barHeight(0) + .onAnimationStart((index: number, targetIndex: number, extraInfo: TabsAnimationEvent) => { + this.tabsIndex = targetIndex; + this.scrollController.scrollToIndex(targetIndex, true, ScrollAlign.START); + } as OnTabsAnimationStartCallback) + } + .height('100%') + .backgroundColor('#F1F1F1') + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + } +} + +/** + * 瀑布流列表项组件布局 + * + * @param listData 组件列表信息 + */ +// TODO:知识点: +// 1.@Reusable标识自定义组件具备可复用的能力,它可以被添加到任意的自定义组件上。 +// 2.复用自定义组件时避免一切可能改变自定义组件的组件树结构和可能使可复用组件中产生重新布局的操作以将组件复用的性能提升到最高。 + +@Reusable +@Component +struct methodPoints { + @State listData: SceneModuleInfo = + new SceneModuleInfo($r('app.media.functional_scenes_address_exchange'), '地址交换动画', + 'addressexchange/AddressExchangeView', '动效', 1); + @State helperUrl: string = 'about://blank'; + @State screenW: number = px2vp(display.getDefaultDisplaySync().width); + @State isNeedClear: boolean = false; + private deviceSize: number = 600; // 依据Navigation的mode属性说明,如使用Auto,窗口宽度>=600vp时,采用Split模式显示;窗口宽度<600vp时,采用Stack模式显示。 + // 当前屏幕折叠态(仅折叠屏设备下有效) + curFoldStatus: display.FoldStatus = display.FoldStatus.FOLD_STATUS_UNKNOWN; + // 从AppStorage中获取设别类别,判断是否为折叠屏 + isFoldable: boolean | undefined = AppStorage.get('isFoldable'); + @State @Watch('onShowReadMeChange') isShowReadMe: boolean = false; + + aboutToAppear(): void { + if (display.isFoldable()) { + this.regDisplayListener(); + } else { + if (this.screenW >= this.deviceSize) { + this.isNeedClear = true; + } else { + this.isNeedClear = false; + } + } + } + + /** + * 组件的生命周期回调,在可复用组件从复用缓存中加入到组件树之前调用 + * @param params:组件更新时所需参数 + */ + aboutToReuse(params: Record): void { + const listData = params['listData']; + if (listData) { + this.listData = listData as SceneModuleInfo; + } + } + + /** + * 注册屏幕状态监听 (仅限折叠屏) + * @returns {void} + */ + regDisplayListener(): void { + this.changeNeedClear(display.getFoldStatus()); + display.on('foldStatusChange', (curFoldStatus: display.FoldStatus) => { + // 同一个状态重复触发不做处理 + if (this.curFoldStatus === curFoldStatus) { + return; + } + // 缓存当前折叠状态 + this.curFoldStatus = curFoldStatus; + this.changeNeedClear(this.curFoldStatus); + }) + } + + changeNeedClear(status: number): void { + if (status === display.FoldStatus.FOLD_STATUS_FOLDED) { + this.isNeedClear = false; + } else { + this.isNeedClear = true; + } + } + + changeHelpUrl(): void { + this.helperUrl = this.listData.helperUrl; + } + + onShowReadMeChange(text: string): void { + if (!this.isShowReadMe) { + + } + } + + // 帮助功能:半模态弹窗显示对应案例README + @Builder + buildReadMeSheet(): void { + Column() { + Row() { + Row() { + Text(this.listData.name) + .textOverflow({ overflow: TextOverflow.Clip } as TextOverflowOptions) + .fontColor(Color.White) + .fontWeight(700) + .fontSize($r('app.integer.nav_destination_title_text_size')) + } + .width($r('app.integer.readme_sheet_text_size')) + + Column() { + Stack() { + Column() { + } + .width($r('app.integer.readme_sheet_size')) + .height($r('app.integer.readme_sheet_size')) + .borderRadius($r('app.integer.nav_destination_title_image_border_radius')) + .backgroundColor(Color.White) + .opacity(0.05) + Image($r('app.media.ic_public_cancel')) + .fillColor(Color.White) + .width($r('app.integer.readme_sheet_cancel_image_width')) + } + } + .onClick((e: ClickEvent) => { + this.isShowReadMe = false; + }) + .justifyContent(FlexAlign.Center) + .width($r('app.integer.readme_sheet_size')) + .height($r('app.integer.readme_sheet_size')) + .borderRadius($r('app.integer.nav_destination_title_image_border_radius')) + } + .padding({ left: $r('app.integer.readme_sheet_padding'), right: $r('app.integer.readme_sheet_padding') } as Padding) + .margin({ top: $r('app.integer.readme_sheet_margin')} as Margin) + .justifyContent(FlexAlign.SpaceBetween) + .width('100%') + } + .width('100%') + .height('100%') + } + + build() { + Column() { + Image($r('app.media.background_pic_3')) + .borderRadius({ + topLeft: 8, + topRight: 8, + bottomLeft: 0, + bottomRight: 0 + } as BorderRadiuses) + .objectFit(ImageFit.Contain) + .width('100%') + + Text(this.listData?.serialNumber?.toString() + '. ' + this.listData.name) + .padding({ + left: 10, + right: 10 + } as Padding) + .width('100%') + .fontColor(Color.Black) + .textAlign(TextAlign.Start) + .maxLines(2) + .fontSize(14) + .margin({ + top: 10, + bottom: 10 + } as Margin) + .textOverflow({ overflow: TextOverflow.Ellipsis } as TextOverflowOptions) + + Row() { + Button($r('app.string.functional_scenes_readme')) + .fontSize(12) + .fontColor(Color.White) + .height(25) + .width(100) + .margin({ left: 6, right: 10 } as Margin) + .gesture( + GestureGroup( + GestureMode.Exclusive, + TapGesture({ fingers: 1, count: 1 }) + .onAction(() => { + this.getUIContext().getRouter().pushUrl({url: 'pages/collapsemenu/Concent'}) + }) + ) + ) + + Text($r('app.string.functional_scenes_difficulty')) + .fontColor(Color.Black) + .opacity(0.6) + .textAlign(TextAlign.Start) + .maxLines(1) + .height(18) + .fontSize(12) + .width(25) + + Rating({ + rating: this.listData.ratingNumber, + indicator: true + } as RatingOptions) + .stars(5) + .width(70) + } + .margin({ bottom: 10 } as Margin) + .width('100%') + .justifyContent(FlexAlign.Start) + } + .shadow(ShadowStyle.OUTER_DEFAULT_XS) + .backgroundColor(Color.White) + .width('100%') + .borderRadius(8) + .margin({ + top: 4, + bottom: 4 + } as Margin) + .onClick((e: ClickEvent) => { + }) + } +} + diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/tabBar/TabBar.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/tabBar/TabBar.ets new file mode 100644 index 0000000000000000000000000000000000000000..2cf1261ba879a0ebb14439273a25d243e8782758 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/tabBar/TabBar.ets @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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, Tabs, TabContent, SubTabBarStyle, + Row, ForEach, Position, Builder, Margin, BarMode, OnTabsAnimationStartCallback, TabsAnimationEvent, TabsOptions, + Color, FlexAlign, $r, Image, SizeOptions, Position, AnimateParam, Flex,FlexDirection,FlexAlign,ItemAlign} 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 { UIContext, Router } from '@ohos.arkui.UIContext' +import router from '@ohos.router' + +@Entry +@Component +export struct TabViewComponent { + // 配置起始的页签索引 + @State selectedIndex: number = 0; + // 初始化Tab控制器 + @State tabArray: string[] = ['首页', '新闻', + '视频', '朋友圈', '我的']; + @State imageArray: string[] = + ['app.media.custom_tab_home', 'app.media.custom_tab_new', 'app.media.custom_tab_video', + 'app.media.custom_tab_friend','app.media.custom_tab_user']; + @State imageClickArray: string[] = + ['app.media.custom_tab_home_selected', 'app.media.custom_tab_new_selected', 'app.media.custom_tab_video_selected', + 'app.media.custom_tab_friend_selected','app.media.custom_tab_user_selected']; + + @State fontColor: string = '#182431'; + @State selectedFontColor: string = '#007DFF'; + + @Builder tabBuilder(item: string, index: number) { + Column() { + if (index === 2) { + Column() { + Image(this.selectedIndex === index ? $r('app.media.custom_tab_video_selected') : + $r('app.media.custom_tab_video')) + .size({ + width: 43, + height: 43 + } as SizeOptions) + } + .width(52) + .height(52) + // TODO:知识点:通过设置borderRadius以及margin的top值实现圆弧外轮廓效果。 + .borderRadius(24) + .margin({ top: -15 } as Margin) + .backgroundColor(Color.White) + .justifyContent(FlexAlign.Center) + } else { + Image(this.selectedIndex === index ? $r(this.imageClickArray[index]) : $r(this.imageArray[index])) + .width(24) + .height(24) + .margin({ bottom: 4 } as Margin) + .size({ + width: 28, + height: 28 + } as SizeOptions)// TODO:知识点:通过offset控制图片的纵向偏移。 + .offset({ + y: (this.selectedIndex === index && + this.selectedIndex !== 2) ? + -3 : 0 + } as Position)// TODO:知识点:组件的某些通用属性变化时,可以通过属性动画animation实现过渡效果。本示例的动画效果是tabBar的图片向上偏移一小段距离 + .animation({ + duration: 400, + iterations: 1, + } as AnimateParam) + } + Text(item) + .fontColor(this.selectedIndex === index ? this.selectedFontColor : this.fontColor) + .fontSize(10) + .fontWeight(500) + .lineHeight(14) + }.width('100%') + .onClick((e: ClickEvent) => { + // 更新被选中的tabBar下标 + this.selectedIndex = index; + }) + } + + build() { + Column() { + Row() { + Text($r('app.string.custom_return')) + } + .margin(3) + .width('100%') + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().back(); + }) + Tabs({ index: this.selectedIndex } as TabsOptions) { + // 首页模块,可根据开发者实际业务替换TabContent中的布局 + TabContent() { + Text($r('app.string.custom_tab_home')) + .fontSize(26) + .padding(20) + } + + // 新闻模块,可根据开发者实际业务替换TabContent中的布局 + TabContent() { + Text($r('app.string.custom_news')) + .fontSize(26) + } + + // 视频模块,可根据开发者实际业务替换TabContent中的布局 + TabContent() { + Text($r('app.string.custom_video')) + .fontSize(26) + } + + // 朋友圈模块,可根据开发者实际业务替换TabContent中的布局 + TabContent() { + Text($r('app.string.custom_friend')) + .fontSize(26) + } + + // 我的模块,可根据开发者实际业务替换TabContent中的布局 + TabContent() { + Text($r('app.string.custom_tab_mine')) + .fontSize(26) + } + } + .vertical(false) + .scrollable(true) + .layoutWeight(1) + .backgroundColor('#ffdbd9d9') + .barHeight(1) + .onAnimationStart((index: number, targetIndex: number) => { + this.selectedIndex = targetIndex; + } as OnTabsAnimationStartCallback) + /** + * 自定义TabBar组件 + * selectedIndex: 配置起始的页签索引 + * tabsInfo: tab数据源,类型为TabBarInfo + */ + Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) { + ForEach(this.tabArray, (item: string, tabBarIndex: number) => { + // 单独一个TabBar组件 + this.tabBuilder(item, tabBarIndex) + }) + } + } + .width('100%') + .height('100%') + } +} + diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/tabContentOverFlow/TabContentOverFlow.ets b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/tabContentOverFlow/TabContentOverFlow.ets new file mode 100644 index 0000000000000000000000000000000000000000..115b54aab519f987404fe37229de71ff7b215874 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/ets/pages/tabContentOverFlow/TabContentOverFlow.ets @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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, Tabs, TabContent, SubTabBarStyle, + Row, ForEach, Position, Builder, Margin, BarMode, OnTabsAnimationStartCallback, TabsAnimationEvent, TabsOptions,animateTo,Alignment, + Color, FlexAlign, $r, Image, SizeOptions, Position, AnimateParam, Flex,FlexDirection,FlexAlign,ItemAlign,VideoController, TranslateOptions, SeekMode, VoidCallback, PlaybackInfo, PreparedInfo, + Video,$rawfile, GestureType, PanGesture, GestureEvent, RelativeContainer, Color, HitTestMode, Visibility} 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 {Callback} from '@ohos.arkui.component' +import hilog from '@ohos.hilog' +import { UIContext, Router } from '@ohos.arkui.UIContext' +import router from '@ohos.router' + +@Entry +@Component +export struct TabContentOverFlowComponent { + @State tabArray: string[] = ['首页', '视频', + '商城', '我的']; + @State imageArray: string[] = + ['app.media.tabcontentoverflow_homepage', 'app.media.tabcontentoverflow_video', 'app.media.tabcontentoverflow_mall', + 'app.media.tabcontentoverflow_mine']; + @State imageClickArray: string[] = + ['app.media.tabcontentoverflow_homepage_filled', 'app.media.tabcontentoverflow_video_filled', + 'app.media.tabcontentoverflow_mall_filled', 'app.media.tabcontentoverflow_mine_filled']; + @State index: number = 1; + @State offsetX: number = 0; // 用来记录实时拖动的距离 + @State positionX: number = 0; // 用来记录拖动后的距离 + @State playTime: string = ''; // 用来记录现在播放的时间 + @State totalTime: number = 0; // 用来记录视频全部时长 + @State isPlay: boolean = false; // 用来控制播放状态 + @State isTouch: boolean = false; // 是否处于拖动状态 + @State isTextButtonVisible: boolean = true; + private isSeek: boolean = false; // 是否拖拽跳转 + private videoController: VideoController = new VideoController(); + private screenW: number = 480; // 获取设备宽度 + + private dragAnimation() { + this.getUIContext()?.animateTo({ + duration: 300, + }, () => { + hilog.info(0x0000, 'testTag', 'animateTo动画触发'); + this.isTouch = true; + }); + } + + @Builder + videoTabContent() { + /** + * TODO: 高性能知识点: 界面嵌套带来了渲染和计算的大量开销,造成性能的衰退。使用扁平化布局优化嵌套层级,建议采用相对布局RelativeContainer进行扁平化布局,有效减少容器的嵌套层级,减少组件的创建时间。 + */ + Column() { + Row() { + Text(' ← 返回') + } + .margin(3) + .width('100%') + .onClick((e: ClickEvent) => { + this.getUIContext().getRouter().back(); + }) + Video({ + src: $r('app.media.tabcontentoverflow_play_video'), + controller: this.videoController + }) + .height('90%') + .width('100%') + .autoPlay(false) + .controls(false) + .onPrepared((event: PreparedInfo) => { + if (event !== undefined) { + this.totalTime = event.duration; + } + } as Callback) + .onFinish(() => { + this.isPlay = false; + } as VoidCallback) + .onUpdate((event: PlaybackInfo) => { + hilog.info(0x0000, 'testTag', '更新:'+event.time); + if (event !== undefined) { + if (!this.isTouch) { + if (!this.isSeek) { + // 当没有进行拖动进度条时,进度条根据播放进度进行变化。 + this.offsetX = + event.time / this.totalTime * (this.screenW - 30); + this.positionX = this.offsetX; + } else { + this.isSeek = false; + } + } + } + } as Callback) + .id('video') + // 播放按钮 + Image($r('app.media.tabcontentoverflow_play')) + .width(50) + .height(50) + .position({x: '45%', y: '45%'} as Position) + .id('image') + .onClick((e: ClickEvent) => { + if (this.isPlay) { + this.isPlay = false; + this.videoController.pause(); + } else { + this.isPlay = true; + this.videoController.start(); + } + }) + .visibility(this.isPlay ? Visibility.Hidden : Visibility.Visible) + // 拖动进度条时展示现在播放哪个到具体的时间点 + Text('00:' + this.playTime) + .fontSize(20) + .width(100) + .height(30) + .id('playTimeText') + .fontColor('#ffff0000') + .visibility(this.isTouch ? Visibility.Visible : Visibility.Hidden) + .margin({ + left: -100, + top: -100 + } as Margin) + // 拖动进度条时展示视频总时长 + Text('/00:' + this.totalTime) + .fontSize(20) + .width(100) + .height(30) + .id('totalTimeText') + .fontColor('#ffffffff') + .visibility(this.isTouch ? Visibility.Visible : Visibility.Hidden) + // TODO: 知识点:使用三个Text组件来模拟播放进度条,第一个text位置不变,宽度不变。第二个text根据this.offsetX来变换宽度。第三个text根据this.offsetX来translate该组件在x轴的位置。 + RelativeContainer() { + Text() + .width(this.screenW - 30) + .height(this.isTouch ? 20 : + 5) + .borderRadius(this.isTouch ? 0 : + 5) + .backgroundColor('#804e4c4d') + .translate({ + y: this.isTouch ? -15 : + 0 + } as TranslateOptions) + .id('text1') + .margin({ + top: 8, + left: 15 + } as Margin) + Text() + .width(this.offsetX) + .height(this.isTouch ? 20 : + 5) + .borderRadius(this.isTouch ? 0 : + 5) + .backgroundColor('#999999') + .translate({ + y: this.isTouch ? -15 : 0 + } as TranslateOptions) + .id('text2') + Text() + .width(20) + .height(20) + .borderRadius(10) + .backgroundColor('#999999') + .translate({ x: this.offsetX } as TranslateOptions) + .visibility(this.isTextButtonVisible ? Visibility.Visible : Visibility.None) + .id('text3') + .margin({ + top: -7.5, + left: -10 + } as Margin) + } + .id('RelativeContainer') + .margin({ + top: 30, + } as Margin) + .width(this.screenW) + .height(70) + // 左右拖动触发该手势事件 + .gesture( + PanGesture() + .onActionStart((event: GestureEvent) => { + hilog.info(0x0000, 'testTag', 'onActionStart触摸准备'); + this.dragAnimation(); + this.isTextButtonVisible = false; + this.isSeek = true; + })/** + * TODO: 性能知识点: onActionUpdate是系统高频回调函数,避免在函数中进行冗余或耗时操作,例如应该减少或避免在函数打印日志,会有较大的性能损耗。 + * 合理使用系统接口,避免冗余操作: README.md + */ + .onActionUpdate((event: GestureEvent) => { + let playTime = + Math.floor(this.offsetX / (this.screenW - 30) * + this.totalTime); + this.offsetX = this.positionX + event.offsetX; + if (this.offsetX <= 0) { + this.offsetX = 0; + } + if (this.offsetX >= this.screenW - 30) { + this.offsetX = this.screenW - 30; + } + if (playTime >= 10) { + this.playTime = (playTime as Number).toString(); + } else { + this.playTime = '0' + (playTime as Number).toString(); + } + }) + .onActionEnd((event: GestureEvent) => { + hilog.info(0x0000, 'testTag', 'onActionEnd触摸结束'); + if (this.positionX === this.offsetX) { // 进度条未发生改变 + this.isSeek = false; + } else { + // 拖动进度条发生改变后通过this.videoController.setCurrentTime来精准定位视频现在播放位置。 + this.videoController.setCurrentTime(Number(((this.offsetX / + (this.screenW - 30) * this.totalTime) as Number).toFixed(3)), + SeekMode.Accurate); + this.positionX = this.offsetX; + } + this.isTextButtonVisible = true; + this.isTouch = false; + }) as GestureType + ) + } + + } + + build() { + Column() { + // TODO: 知识点:将barHeight设置为0,预留60vp给自定义tabBar,TabContent的高度则可以使用calc(100% - 60vp)获取。 + Tabs({ index: this.index } as TabsOptions) { + TabContent() { + Text($r('app.string.custom_home')) + .fontSize(20) + } + .align(Alignment.Center) + .height('calc(100% - 60vp)') + .width('100%') + + TabContent() { + this.videoTabContent(); + } + .align(Alignment.Top) + + TabContent() { + Text($r('app.string.custom_store')) + .fontSize(20) + } + .align(Alignment.Center) + .height('calc(100% - 60vp)') + .width('100%') + + TabContent() { + Text($r('app.string.custom_my')) + .fontSize(20) + } + .align(Alignment.Center) + .height('calc(100% - 60vp)') + .width('100%') + } + // TODO: 知识点:将zIndex设置为2,TabContent将在tabBar之上,显示的效果就是TabContent外溢的部分在tabBar上。 + .zIndex(2) + .scrollable(false) + .barHeight(1) + .animationDuration(100) + // TODO: 知识点:hitTestBehavior属性可以实现在复杂的多层级场景下,一些组件能够响应手势和事件,而一些组件不能响应手势和事件。HitTestMode.Transparent的效果为,自身响应触摸测试,不会阻塞兄弟节点的触摸测试。 + .hitTestBehavior(HitTestMode.Transparent) + .id('tabs') + + // 页签 + Row() { + ForEach(this.tabArray, (item: string, index: number) => { + Column() { + Image(this.index === index ? $r(this.imageClickArray[index]) : $r(this.imageArray[index])) + .width(30) + .height(30) + Text(item) + .fontSize(12) + .fontColor(this.index === index ? '#e40d0d' : + '#FFFFFFFF') + } + .width(50) + .margin({ top: 10 } as Margin) + // 为将底部视图扩展到非安全区域,可将原本60vp的高度设置为100vp。 + .height(100) + .onClick((e: ClickEvent) => { + hilog.info(0x0000, 'testTag', 'tabs点击'); + this.index = index; + }) + }) + } + .width('100%') + .backgroundColor('#FF000000') + .margin({top: '-60vp'} as Margin) + .justifyContent(FlexAlign.SpaceAround) + .id('tabbar') + } + } +} \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/module.json5 b/code/ArkTS1.2/TabsSample/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f95f9a6e69c03b1b6da379b36fc7aa9ee2c41ac4 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/entry/src/main/resources/base/element/color.json b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..7bccbbf2e9ec34fdab062feaef5506390d2cfa9a --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/element/color.json @@ -0,0 +1,24 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + }, + { + "name": "font_color_dark", + "value": "#000000" + }, + { + "name": "helper_bindsheet_bgc", + "value": "#303643" + }, + { + "name": "background_blur_selected_text_color", + "value": "#FFEC0707" + }, + { + "name": "background_blur_tabs_bar_background_color", + "value": "#FFE9E9E9" + } + ] +} \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/element/float.json b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/element/integer.json b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/element/integer.json new file mode 100644 index 0000000000000000000000000000000000000000..ce96b23157ebaf0cddbee69137edb1458ea6e143 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/element/integer.json @@ -0,0 +1,248 @@ +{ + "integer": [ + { + "name": "helper_size", + "value": 30 + }, + { + "name": "nav_destination_title_image_size", + "value": 28 + }, + { + "name": "nav_destination_title_image_background_size", + "value": 40 + }, + { + "name": "nav_destination_title_text_size", + "value": 20 + }, + { + "name": "nav_destination_title_text_margin", + "value": 9 + }, + { + "name": "nav_destination_title_width", + "value": 328 + }, + { + "name": "nav_destination_title_height", + "value": 56 + }, + { + "name": "nav_destination_title_bottom", + "value": 8 + }, + { + "name": "nav_destination_title_image_border_radius", + "value": 100 + }, + { + "name": "swiper_width", + "value": 353 + }, + { + "name": "swiper_height", + "value": 160 + }, + { + "name": "swiper_border_radius", + "value": 16 + }, + { + "name": "swiper_margin_top", + "value": 8 + }, + { + "name": "swiper_margin_bottom", + "value": 8 + }, + { + "name": "helper_help_image_size", + "value": 18 + }, + { + "name": "helper_width", + "value": 40 + }, + { + "name": "helper_border_radius", + "value": 40 + }, + { + "name": "readme_sheet_text_size", + "value": 276 + }, + { + "name": "readme_sheet_size", + "value": 40 + }, + { + "name": "readme_sheet_cancel_image_width", + "value": 20 + }, + { + "name": "readme_sheet_padding", + "value": 17 + }, + { + "name": "readme_sheet_margin", + "value": 16 + }, + { + "name": "nav_destination_padding_bottom", + "value": 64 + }, + { + "name": "nav_destination_padding_bottom_no_title", + "value": 8 + }, + { + "name": "nav_destination_title_text_width", + "value": 250 + }, + { + "name": "collapse_menu_list_border_radius", + "value": 12 + }, + { + "name": "collapse_menu_list_margin_top", + "value": 4 + }, + { + "name": "collapse_menu_list_padding_right", + "value": 12 + }, + { + "name": "collapse_menu_list_margin_left", + "value": 12 + }, + { + "name": "collapse_menu_list_item_margin_top", + "value": 6 + }, + { + "name": "collapse_menu_text_font_size", + "value": 16 + }, + { + "name": "collapse_menu_text_margin_left", + "value": 16 + }, + { + "name": "collapse_menu_arrow_unfold_width", + "value": 24 + }, + { + "name": "collapse_menu_arrow_width", + "value": 12 + }, + { + "name": "collapse_menu_arrow_fold_margin_right", + "value": 6 + }, + { + "name": "collapse_menu_divide_margin_left", + "value": 42 + }, + { + "name": "collapse_menu_divide_margin_right", + "value": 8 + }, + { + "name": "collapse_menu_fourth_level_height", + "value": 48 + }, + { + "name": "background_blur_tab_bar_height", + "value": 60 + }, + { + "name": "functional_scenes_tab_bar_background_width1", + "value": 97 + }, + { + "name": "functional_scenes_tab_bar_background_width2", + "value": 71 + }, + { + "name": "functional_scenes_tab_bar_background_height", + "value": 38 + }, + { + "name": "functional_scenes_tab_bar_background_border_radius", + "value": 21 + }, + { + "name": "functional_scenes_tab_bar_margin", + "value": 9 + }, + { + "name": "functional_scenes_tab_bar_list_margin", + "value": 3 + }, + { + "name": "functional_scenes_tab_bar_list_height", + "value": 38 + }, + { + "name": "functional_scenes_tab_bar_list_padding", + "value": 46 + }, + { + "name": "functional_scenes_tab_bar_image_more", + "value": 20 + }, + { + "name": "functional_scenes_tab_bar_image_more_background_size", + "value": 43 + }, + { + "name": "functional_scenes_tab_bar_image_more_border_radius", + "value": 100 + }, + { + "name": "functional_scenes_tab_bar_image_more_row_width", + "value": 60 + }, + { + "name": "functional_scenes_tab_bar_image_more_row_height", + "value": 43 + }, + { + "name": "functional_scenes_tab_bar_image_more_row_padding", + "value": 13 + }, + { + "name": "functional_scenes_tab_bar_image_more_row_margin", + "value": 8 + }, + { + "name": "functional_scenes_item_width", + "value": 177 + }, + { + "name": "functional_scenes_water_flow_padding_bottom", + "value": 53 + }, + { + "name": "functional_scenes_item_foldable_width", + "value": 158 + }, + { + "name": "functional_scenes_readme_width", + "value": 60 + }, + { + "name": "functional_scenes_readme_height", + "value": 25 + }, + { + "name": "functional_scenes_readme_font_size", + "value": 12 + }, + { + "name": "functional_scenes_rating_width", + "value": 70 + } + ] +} diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/element/string.json b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..864f093499d0eeb7c2c1092d34d433a48bf75687 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/element/string.json @@ -0,0 +1,200 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "TabsSample" + }, + { + "name": "background_blur_main", + "value": "背景模糊" + }, + { + "name": "background_blur_discover", + "value": "折叠面板案例" + }, + { + "name": "background_blur_hot", + "value": "主页瀑布流实现案例" + }, + { + "name": "background_blur_my", + "value": "我的" + }, + { + "name": "functional_scenes_page_show", + "value": "page from package" + }, + { + "name": "functional_scenes_difficulty", + "value": "难度 " + }, + { + "name": "functional_scenes_tab_title_data_Native", + "value": "Native" + }, + { + "name": "functional_scenes_tab_title_data_arkui", + "value": "UI布局" + }, + { + "name": "functional_scenes_tab_title_data_other", + "value": "其他" + }, + { + "name": "functional_scenes_tab_title_data_tripartite_library", + "value": "三方库" + }, + { + "name": "functional_scenes_tab_title_data_dynamic_effect", + "value": "动效" + }, + { + "name": "functional_scenes_main_page_top_borderRadius", + "value": "8" + }, + { + "name": "functional_scenes_main_page_list_borderRadius", + "value": "8" + }, + { + "name": "functional_scenes_main_page_padding1", + "value": "10" + }, + { + "name": "functional_scenes_main_page_padding2", + "value": "12" + }, + { + "name": "functional_scenes_main_page_padding3", + "value": "16" + }, + { + "name": "functional_scenes_main_page_padding4", + "value": "18" + }, + { + "name": "functional_scenes_main_page_padding5", + "value": "8" + }, + { + "name": "functional_scenes_main_page_padding6", + "value": "10" + }, + { + "name": "functional_scenes_main_page_padding_list_bottom", + "value": "350" + }, + { + "name": "functional_scenes_main_page_swiper_height", + "value": "200" + }, + { + "name": "functional_scenes_main_page_text_height", + "value": "18" + }, + { + "name": "functional_scenes_main_page_text_width", + "value": "25" + }, + { + "name": "functional_scenes_main_page_text_font_size", + "value": "12" + }, + { + "name": "functional_scenes_main_page_margin1", + "value": "10" + }, + { + "name": "functional_scenes_main_page_margin2", + "value": "12" + }, + { + "name": "functional_scenes_main_page_tab_text_underline", + "value": "2" + }, + { + "name": "functional_scenes_main_page_water_flow_gap", + "value": "6" + }, + { + "name": "functional_scenes_item_gap_half", + "value": "4" + }, + { + "name": "functional_scenes_network_message", + "value": "此功能需联网使用" + }, + { + "name": "functional_scenes_readme", + "value": "查看源码" + }, + { + "name": "functional_scenes_full_size", + "value": "100%" + }, + { + "name": "custom_tab_home", + "value": "首页" + }, + { + "name": "custom_tab_news", + "value": "新品" + }, + { + "name": "custom_tab_friend", + "value": "商城" + }, + { + "name": "custom_news", + "value": "新闻" + }, + { + "name": "custom_friend", + "value": "朋友圈" + }, + { + "name": "custom_video", + "value": "视频" + }, + { + "name": "custom_tab_mine", + "value": "我的" + }, + { + "name": "custom_return", + "value": " ← 返回" + }, + { + "name": "custom_detail", + "value": "详情内容" + }, + { + "name": "custom_tab_bar", + "value": "自定义TabBar页签案例" + }, + { + "name": "custom_tab_Content", + "value": "tabContent内容可以在tabBar上显示并响应滑动事件案例" + }, + { + "name": "custom_store", + "value": "商城界面,仅供Tabs展示。" + }, + { + "name": "custom_my", + "value": "我的界面,仅供Tabs展示。" + }, + { + "name": "custom_home", + "value": "我的首页,仅供Tabs展示。" + } + ] +} \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/back_index.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/back_index.svg new file mode 100644 index 0000000000000000000000000000000000000000..0818cbcea6789ebc5b4f337fb232252299b7e45c --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/back_index.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_1.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_1.png new file mode 100644 index 0000000000000000000000000000000000000000..74ce3af508d55e47d47a49450bdc745a48a627bb Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_1.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_2.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_2.png new file mode 100644 index 0000000000000000000000000000000000000000..5411e7ac8de507b7219a1e2d073c98ec725795f5 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_2.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_3.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_3.png new file mode 100644 index 0000000000000000000000000000000000000000..431bc51bab0d0e21736c89fd9eb3836212f81969 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_3.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_4.webp b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_4.webp new file mode 100644 index 0000000000000000000000000000000000000000..3abb5a617a2b3cd397606343ce9d5f017bf0ca80 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/background_pic_4.webp differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_find_normal.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_find_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..69eafb561c07a739bc29b15f38c7fc4e08c346d7 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_find_normal.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_find_select.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_find_select.png new file mode 100644 index 0000000000000000000000000000000000000000..19aa62ec133a06053220699ab3e1d963fd7052b3 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_find_select.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_hot_normal.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_hot_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..3310b14196a8f2dadf76bbde2acae404c956f5e1 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_hot_normal.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_hot_select.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_hot_select.png new file mode 100644 index 0000000000000000000000000000000000000000..706e7c8dcd321b7b9c1a2e98c0481dc8e64306e6 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_hot_select.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_main_normal.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_main_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..ada79f5589d5af7c8a8ed9fa67dfa9f07435f2ee Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_main_normal.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_main_select.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_main_select.png new file mode 100644 index 0000000000000000000000000000000000000000..af4f621097b73b579741d17a549a01c1b9dfb482 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_main_select.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_my_normal.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_my_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..7e9c0747798aa3b4a7b385bc3957c94fa8dbcab3 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_my_normal.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_my_select.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_my_select.png new file mode 100644 index 0000000000000000000000000000000000000000..7895b8cb46876f1ad664cf413545a8f6f52b9957 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/backgroundblur_my_select.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_cart.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_cart.png new file mode 100644 index 0000000000000000000000000000000000000000..b7cc936378606e7905915498a037f2c202acf8ff Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_cart.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_default_icon.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_default_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_default_icon.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_friend.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_friend.svg new file mode 100644 index 0000000000000000000000000000000000000000..37a37252b40ee12e8aa6db651e52f4f96c1d5b7a --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_friend.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_friend_selected.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_friend_selected.svg new file mode 100644 index 0000000000000000000000000000000000000000..db908b3247d4a387517af576a9d26e5bb4f51b96 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_friend_selected.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_home.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_home.svg new file mode 100644 index 0000000000000000000000000000000000000000..7392fa0daa0dec33090bbc10342bfa9aacfef2e6 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_home.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_home + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_home_selected.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_home_selected.svg new file mode 100644 index 0000000000000000000000000000000000000000..751a5c64cff15034e33f9eef3230636b0081c546 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_home_selected.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_home_filled + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_new.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_new.svg new file mode 100644 index 0000000000000000000000000000000000000000..41da014aa7ec77d322e070b0bf28b7cfce2e5051 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_new.svg @@ -0,0 +1,7 @@ + + + ic_gallery_discover + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_new_selected.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_new_selected.svg new file mode 100644 index 0000000000000000000000000000000000000000..40e140b5a2203bd0cf6b34c117dadc0ce7da13d4 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_new_selected.svg @@ -0,0 +1,8 @@ + + + xxhdpi/ic/navigation/discover_action + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_user.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_user.svg new file mode 100644 index 0000000000000000000000000000000000000000..a4c28ffbc49f7eb66f9ade5ab76f4cfb71469170 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_user.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_contacts + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_user_selected.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_user_selected.svg new file mode 100644 index 0000000000000000000000000000000000000000..07e3a3daa5225872b7139417f2dbecd9440d122a --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_user_selected.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_contacts_filled + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_video.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_video.svg new file mode 100644 index 0000000000000000000000000000000000000000..f5cd90d004e9812c74ef9ac4224de439b5070541 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_video.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_video_selected.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_video_selected.svg new file mode 100644 index 0000000000000000000000000000000000000000..d9fe4874cb1742f5cdff75867a25b2221d0dc78f --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/custom_tab_video_selected.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example1.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example1.png new file mode 100644 index 0000000000000000000000000000000000000000..9b92f49c43626e9207d870417c93dc2d9c290bad Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example1.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example2.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example2.png new file mode 100644 index 0000000000000000000000000000000000000000..a0699f26440e5f8688fabea9724d217123ce7982 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example2.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example3.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example3.png new file mode 100644 index 0000000000000000000000000000000000000000..4710153e08fbf1c266758ad8d4e94a0243474d58 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example3.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example4.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example4.png new file mode 100644 index 0000000000000000000000000000000000000000..b30bc1dfd0d44affa88f2dbefde96add61c7ecf7 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/example4.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/foreground.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/foreground.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/functional_scenes_address_exchange.gif b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/functional_scenes_address_exchange.gif new file mode 100644 index 0000000000000000000000000000000000000000..bd9a070650d123b2231d3384e677767830622120 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/functional_scenes_address_exchange.gif differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_down_arrow.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_down_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..351af3d6742d880a5fe8a06d57bff53a6624c85b Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_down_arrow.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_public_cancel.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_public_cancel.svg new file mode 100644 index 0000000000000000000000000000000000000000..11708cc009ca6519b732405a53da6e79ab99f989 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_public_cancel.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_cancel + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_public_more.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_public_more.svg new file mode 100644 index 0000000000000000000000000000000000000000..88fd9e2a80e4c489790c3f835d2bedd7b9a9e330 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_public_more.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_more + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_right_arrow.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_right_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..d5dc67eec85664a24889404b40174e62278f3c74 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/ic_right_arrow.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/layered_image.json b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/entry/src/main/resources/base/media/main.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/main.png new file mode 100644 index 0000000000000000000000000000000000000000..55a435bb554d47c24d6c759e227aa8128cc2d267 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/main.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/startIcon.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/startIcon.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_cart.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_cart.png new file mode 100644 index 0000000000000000000000000000000000000000..b7cc936378606e7905915498a037f2c202acf8ff Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_cart.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_cart_selected.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_cart_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..b49a8b0cbde6bd938a1944ca26283d77facc54fd Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_cart_selected.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_community.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_community.svg new file mode 100644 index 0000000000000000000000000000000000000000..4036c8ec8019c307db7e88a909833436d62b63f2 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_community.svg @@ -0,0 +1,17 @@ + + + discover_shequ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_community_selected.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_community_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..3f922ba641740d06c53c2d90941ab806414275f0 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_community_selected.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_home.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_home.png new file mode 100644 index 0000000000000000000000000000000000000000..3d6ea867d64f3e90b278ec86f10ee39de825781f Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_home.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_new.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_new.png new file mode 100644 index 0000000000000000000000000000000000000000..81efdfd2eb83a97dbf59fb28e5baa4de1fc5f62c Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_new.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_new_selected.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_new_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..8bad8514f88c682521a790486e720858fd16afd4 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_new_selected.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_tabBarMain.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_tabBarMain.png new file mode 100644 index 0000000000000000000000000000000000000000..72852d0769e6e8db449f5273ca0943d908123a9b Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_tabBarMain.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_user.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_user.png new file mode 100644 index 0000000000000000000000000000000000000000..19d7c4de69f30526df035f37fd4a494e510d44a8 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_user.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_user_selected.png b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_user_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..eb04cc0172cec9bb87de3658619927631cbe2823 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tab_user_selected.png differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_homepage.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_homepage.svg new file mode 100644 index 0000000000000000000000000000000000000000..cd456ad983dd898f22b2cd28892aab323d3a8280 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_homepage.svg @@ -0,0 +1,13 @@ + + + ic_edit company + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_homepage_filled.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_homepage_filled.svg new file mode 100644 index 0000000000000000000000000000000000000000..336374e3489a254c74aa6d402afb423d005fc0cf --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_homepage_filled.svg @@ -0,0 +1,13 @@ + + + ic_edit company_filled + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mall.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mall.svg new file mode 100644 index 0000000000000000000000000000000000000000..486947ef9ca03bfdbd7de48d26164e420a8880f9 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mall.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_appstore + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mall_filled.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mall_filled.svg new file mode 100644 index 0000000000000000000000000000000000000000..302452914b5467edb8715cdeb764500d26b56614 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mall_filled.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_appstore_filled + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mine.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mine.svg new file mode 100644 index 0000000000000000000000000000000000000000..271077d92a4f6bcb2e89e365b5f7e9f4d8f7d270 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mine.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_contacts + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mine_filled.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mine_filled.svg new file mode 100644 index 0000000000000000000000000000000000000000..c8cb6dede78796728f24f27b2c9c02af3b2c6a37 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_mine_filled.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_contacts_filled + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_play.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_play.svg new file mode 100644 index 0000000000000000000000000000000000000000..fd027d5b3e27c8bab499c8ad84cf55734abd13d4 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_play.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_play + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_play_video.MP4 b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_play_video.MP4 new file mode 100644 index 0000000000000000000000000000000000000000..9bcf0eaee14311ad17b1dd01043e4da04cbff4c5 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_play_video.MP4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48f6dc6969fd44c46ad3e3940e13b770d2a383ecaa61ca36a9da8d42e69835c3 +size 3043166 diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_preview.jpg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_preview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..391c783cb7d1ae1485ca9f02e9d57e02f5531a81 Binary files /dev/null and b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_preview.jpg differ diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_video.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_video.svg new file mode 100644 index 0000000000000000000000000000000000000000..4efd2acd00dec11e18b69d57a1aa2cb490c22c3f --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_video.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_play_norm + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_video_filled.svg b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_video_filled.svg new file mode 100644 index 0000000000000000000000000000000000000000..39ed68dbc9c54a368f9dbb084b0162c7eef12788 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/media/tabcontentoverflow_video_filled.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_play_norm + + + + + + + + + + \ No newline at end of file diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/profile/backup_config.json b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/entry/src/main/resources/base/profile/main_pages.json b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..963e00499cda601f41e50576498ed9e47dbb44b4 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,10 @@ +{ + "src": [ + "pages/Index", + "pages/tabBar/TabBar", + "pages/tabContentOverFlow/TabContentOverFlow", + "pages/functionalScenes/FunctionalScenes", + "pages/collapsemenu/CollapseMenuSection", + "pages/collapsemenu/Concent" + ] +} diff --git a/code/ArkTS1.2/TabsSample/entry/src/main/resources/dark/element/color.json b/code/ArkTS1.2/TabsSample/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/hvigor/hvigor-config.json5 b/code/ArkTS1.2/TabsSample/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..57c58e3641a0b085f39f7f137b9a938ecb20f2fd --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/hvigorfile.ts b/code/ArkTS1.2/TabsSample/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f435606b5766719f7203539113d84a2b281b0353 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/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/TabsSample/oh-package.json5 b/code/ArkTS1.2/TabsSample/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b6f7090658c0e69d5582af5d236fde4eab954ed6 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/oh-package.json5 @@ -0,0 +1,34 @@ +/** + * + * 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": { + } +} diff --git a/code/ArkTS1.2/TabsSample/ohosTest.md b/code/ArkTS1.2/TabsSample/ohosTest.md new file mode 100644 index 0000000000000000000000000000000000000000..16b56754c3e342a9204940443f8e7c7f2985f409 --- /dev/null +++ b/code/ArkTS1.2/TabsSample/ohosTest.md @@ -0,0 +1,11 @@ +# 主页Tabs嵌套场景测试用例 + +## 用例表 + +| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 | +|-----------------------------------|-------------------------------------|----------------------|------------------------------------|------|------| +| 顶部分栏按钮切换事件 | 1. 需在真机测试
2. 构建并安装测试hap
3.进入【主页瀑布流实现】| 1、点击分栏按钮
2、左右滑动屏幕
3、点击下拉菜单按钮,选中一个Tab| 1、进入对应分栏,展示对应案例数据
2、分栏跟随滑动进行左右滚动显示
3、菜单按钮与分栏联动,同步变化 | 否 | Pass | +| 点击案例跳转页面详情 | 1. 需在真机测试
2. 构建并安装测试hap
3.进入【主页瀑布流实现】| 1、点击案例中的查看源码按钮
2、点击左上角返回按钮 | 1、正常跳转到详情页面
2、返回上一级页面 | 否 | Pass | +| 折叠面板展开收起 | 1. 需在真机测试
2. 构建并安装测试hap
3.进入【折叠面板案例】| 1、点击一级分类面板展开按钮
2、点击一级分类面板收起按钮 | 1、折叠面板可正常展开
2、折叠面板可正常收起| 否 | Pass | +| 滑动tabBar区域拉动进度条 | 1. 需在真机测试
2. 构建并安装测试hap
3.进入【tabContent内容可以在tabBar上显示并响应滑动事件案例】| 1、点击视频中央的播放按钮
2、滑动进度按钮以及进度按钮下方区域 | 1、视频开始正常播放
2、视频播放进度随着滑动调整| 否 | Pass | +| tabBar页面切换显示 | 1. 需在真机测试
2. 构建并安装测试hap
3.进入【自定义TabBar页签案例】| 1、点击页面下方的Tab | 1、进入Tab对应的页面| 否 | Pass | \ No newline at end of file