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