diff --git a/Ability/PageAbility/LICENSE b/Ability/PageAbility/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..80576ef141485b36eea4aebf25af97020bc2de44 --- /dev/null +++ b/Ability/PageAbility/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + + 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/Ability/PageAbility/README.md b/Ability/PageAbility/README.md index 1586e959ede664d5e6d51c66ca6e914593515558..6d35cf797453ec067ac8f2560f85d8c3273fa830 100644 --- a/Ability/PageAbility/README.md +++ b/Ability/PageAbility/README.md @@ -1,2 +1,164 @@ -tmp +# 介绍 +## 应用场景 + +本篇Codelab主要是介绍在OpenHarmony上如何进行Ability内部的页面跳转和Ability之间的页面跳转。本片Codelab基于eTS语言。应用场景主要分为三种: + +1、同一个Ability内部页面跳转; + +2、跳转到指定其他Ability的首页; + +3、跳转到指定其他Ability的指定页面(非首页); + +**图 1** +![](figures/zh-cn_image_0000001234372249.png "zh-cn_image_0000001234372249") + +# 相关概念 + +Ability:Ability是应用所具备能力的抽象,也是应用程序的重要组成部分。 + +[PageAbility](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ability/page-ability.md):Page模板(以下简称“Page”)是FA唯一支持的模板,用于提供与用户交互的能力。 + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 任务一:Ability内页面跳转 + +- 新建项目时language选择eTS; + +- 在eTS目录如下,pages目录下有index.ets和second.ets; + + ![](figures/zh-cn_image_0000001188791474.png) + + 1. 在index.ets中引入router模块; + + ``` + import router from '@system.router'; + ``` + + 2. 为按钮添加文本、样式和点击事件,点击后跳转到second页面,使用router.push实现跳转; + + ``` + Button() { + Text('Click to ability1 second page') + .fontSize(25) + .fontWeight(FontWeight.Medium) + } + .padding({ top: 20, left: 20, right: 20, bottom: 20 }) + .margin({ top: 20 }) + .onClick(() => { + router.push({ uri: 'pages/second' }) + }) + ``` + +# 任务二:跳转到指定Ability首页 + +- 新建Ability,名为MainAbility2,在ets目录下右键新建New-\>Ability-\>Empty Page Ability\(eTS\); + +![](figures/zh-cn_image_0000001189113124.png) + +- 目录结构如下: + +![](figures/zh-cn_image_0000001234154343.png) + +1. 在MainAbility/pages/index.ets中引入featureAbility模块; + + ``` + import featureAbility from '@ohos.ability.featureAbility'; + ``` + +2. 在MainAbility/pages/index.ets中添加按钮,并为按钮添加文本、样式和点击事件,点击后跳转到MainAbility2的index页面,通过featureAbility.startAbility实现,调用featureAbility.startAbility时,这里参数want里主要传递bundleName和abilityName;详情请参看[启动本地PageAbility](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ability/page-ability.md#%E5%90%AF%E5%8A%A8%E6%9C%AC%E5%9C%B0pageability)。点击按钮触发点击事件后会默认跳转到MainAbility2的index页面。 + + ``` + Button() { + Text('Click to ability2 index page') + .fontSize(25) + } + .padding({ top: 20, left: 20, right: 20, bottom: 20 }) + .margin({ top: 20 }) + .onClick(() => { + //启动Ability + let str = { + "want": { + "bundleName": "com.example.pageabilityopenh", + "abilityName": "com.example.pageabilityopenh.MainAbility2", + }, + }; + featureAbility.startAbility(str) + .then((data) => { + console.info('Operation successful. Data: ' + JSON.stringify(data)) + }).catch((error) => { + console.error('Operation failed. Cause: ' + JSON.stringify(error)); + }) + }) + ``` + +# 任务三:跳转到指定Ability指定页面(非首页) + +要跳转到指定Ability指定页面,只需要在本文档任务二的基础上,另外在want里添加parameters参数,url设置为指定页面,如:‘pages/second’即可。 + +``` +Button() { + Text('Click to ability2 second page') + .fontSize(25) + } + .padding({ top: 20, left: 20, right: 20, bottom: 20 }) + .margin({ top: 20 }) + .onClick(() => { + //启动ability + let str = { + "want": { + "bundleName": "com.example.pageabilityopenh", + "abilityName": "com.example.pageabilityopenh.MainAbility2", + "parameters": { + url: 'pages/second' + } + }, + }; + featureAbility.startAbility(str) + .then((data) => { + console.info('Operation successful. Data: ' + JSON.stringify(data)) + }).catch((error) => { + console.error('Operation failed. Cause: ' + JSON.stringify(error)); + }) + }) +``` + +# 恭喜你 + +学会了如何进行Ability 内部的页面跳转和Ability之间的页面跳转。即如下三种场景: + +1、同一个Ability内部页面跳转; + +2、跳转到指定其他Ability的首页; + +3、跳转到指定其他Ability的指定页面(非首页); + +# 参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/Ability/PageAbility) diff --git a/Ability/PageAbility/build.gradle b/Ability/PageAbility/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..8091e0ece10575993ba570722aadd6788144f460 --- /dev/null +++ b/Ability/PageAbility/build.gradle @@ -0,0 +1,34 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + supportSystem "standard" +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } + dependencies { + classpath 'com.huawei.ohos:hap:3.0.3.4' + classpath 'com.huawei.ohos:decctest:1.2.6.0' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } +} diff --git a/Ability/PageAbility/entry/.gitignore b/Ability/PageAbility/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7d5b7a94f4dcf381f03ff21f28f8a2494b58023f --- /dev/null +++ b/Ability/PageAbility/entry/.gitignore @@ -0,0 +1,2 @@ +/build +/node_modules diff --git a/Ability/PageAbility/entry/build.gradle b/Ability/PageAbility/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..1587dd1948941f3eaaf092ae6cae7969cb6895ff --- /dev/null +++ b/Ability/PageAbility/entry/build.gradle @@ -0,0 +1,21 @@ +apply plugin: 'com.huawei.ohos.hap' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + defaultConfig { + compatibleSdkVersion 7 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13.1' +} diff --git a/Ability/PageAbility/entry/proguard-rules.pro b/Ability/PageAbility/entry/proguard-rules.pro new file mode 100644 index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a --- /dev/null +++ b/Ability/PageAbility/entry/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/Ability/PageAbility/entry/src/main/config.json b/Ability/PageAbility/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..55adb1573389502acec92a283847fbe3ee71249c --- /dev/null +++ b/Ability/PageAbility/entry/src/main/config.json @@ -0,0 +1,94 @@ +{ + "app": { + "bundleName": "com.example.pageabilityopenh", + "vendor": "example", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "com.example.pageabilityopenh", + "name": ".MyApplication", + "mainAbility": ".MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "visible": true, + "srcPath": "MainAbility", + "name": ".MainAbility", + "srcLanguage": "ets", + "icon": "$media:icon", + "description": "$string:description_mainability", + "formsEnabled": false, + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + }, + { + "orientation": "unspecified", + "srcPath": "MainAbility2", + "name": ".MainAbility2", + "srcLanguage": "ets", + "icon": "$media:icon", + "description": "$string:description_mainability2", + "formsEnabled": false, + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "mode": { + "syntax": "ets", + "type": "pageAbility" + }, + "pages": [ + "pages/index", + "pages/second" + ], + "name": ".MainAbility", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + }, + { + "mode": { + "syntax": "ets", + "type": "pageAbility" + }, + "pages": [ + "pages/index", + "pages/second" + ], + "name": ".MainAbility2", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} \ No newline at end of file diff --git a/Ability/PageAbility/entry/src/main/ets/MainAbility/app.ets b/Ability/PageAbility/entry/src/main/ets/MainAbility/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..b7a0995c8e441cac86e21e06e7c9071664482b1c --- /dev/null +++ b/Ability/PageAbility/entry/src/main/ets/MainAbility/app.ets @@ -0,0 +1,8 @@ +export default { + onCreate() { + console.info('Application onCreate') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} \ No newline at end of file diff --git a/Ability/PageAbility/entry/src/main/ets/MainAbility/pages/index.ets b/Ability/PageAbility/entry/src/main/ets/MainAbility/pages/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..56c1c1f179f141cd423b032a6d1a29ef7b0fe8a2 --- /dev/null +++ b/Ability/PageAbility/entry/src/main/ets/MainAbility/pages/index.ets @@ -0,0 +1,76 @@ +import router from '@system.router'; +import featureAbility from '@ohos.ability.featureAbility'; + +@Entry +@Component +struct Index { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Text('This is ability1 index page') + .fontSize(25) + .fontWeight(FontWeight.Medium) + Button() { + Text('Click to ability1 second page') + .fontSize(25) + .fontWeight(FontWeight.Medium) + .margin({left:20,right:20}) + } + .padding({ top: 20, left: 20, right: 20, bottom: 20 }) + .margin({ top: 20 }) + .onClick(() => { + router.push({ uri: 'pages/second' }) + }) + + Button() { + Text('Click to ability2 index page') + .fontSize(25) + .margin({left:20,right:20}) + } + .padding({ top: 20, left: 20, right: 20, bottom: 20 }) + .margin({ top: 20 }) + .onClick(() => { + //启动ability + let str = { + "want": { + "bundleName": "com.example.pageabilityopenh", + "abilityName": "com.example.pageabilityopenh.MainAbility2", + }, + }; + featureAbility.startAbility(str) + .then((data) => { + console.info('Operation successful. Data: ' + JSON.stringify(data)) + }).catch((error) => { + console.error('Operation failed. Cause: ' + JSON.stringify(error)); + }) + }) + + Button() { + Text('Click to ability2 second page') + .fontSize(25) + .margin({left:20,right:20}) + } + .padding({ top: 20, left: 20, right: 20, bottom: 20 }) + .margin({ top: 20 }) + .onClick(() => { + //启动ability + let str = { + "want": { + "bundleName": "com.example.pageabilityopenh", + "abilityName": "com.example.pageabilityopenh.MainAbility2", + "parameters": { + url: 'pages/second' + } + }, + }; + featureAbility.startAbility(str) + .then((data) => { + console.info('Operation successful. Data: ' + JSON.stringify(data)) + }).catch((error) => { + console.error('Operation failed. Cause: ' + JSON.stringify(error)); + }) + }) + } + .width('100%') + .height('100%') + } +} \ No newline at end of file diff --git a/Ability/PageAbility/entry/src/main/ets/MainAbility/pages/second.ets b/Ability/PageAbility/entry/src/main/ets/MainAbility/pages/second.ets new file mode 100644 index 0000000000000000000000000000000000000000..e496b61a097a8600cb2ef6b2881cc39a8979b69e --- /dev/null +++ b/Ability/PageAbility/entry/src/main/ets/MainAbility/pages/second.ets @@ -0,0 +1,17 @@ +@Entry +@Component +struct Second { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Button() { + Text('This is ability1 second page') + .fontSize(25) + .fontWeight(FontWeight.Medium) + .margin({left:20,right:20}) + } + .padding({ top: 20, left: 20, right: 20, bottom: 20 }) + } + .width('100%') + .height('100%') + } +} \ No newline at end of file diff --git a/Ability/PageAbility/entry/src/main/ets/MainAbility2/app.ets b/Ability/PageAbility/entry/src/main/ets/MainAbility2/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..b7a0995c8e441cac86e21e06e7c9071664482b1c --- /dev/null +++ b/Ability/PageAbility/entry/src/main/ets/MainAbility2/app.ets @@ -0,0 +1,8 @@ +export default { + onCreate() { + console.info('Application onCreate') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} \ No newline at end of file diff --git a/Ability/PageAbility/entry/src/main/ets/MainAbility2/pages/index.ets b/Ability/PageAbility/entry/src/main/ets/MainAbility2/pages/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..4300ec8f16e6fe47986e99de7b7e44d050fb4178 --- /dev/null +++ b/Ability/PageAbility/entry/src/main/ets/MainAbility2/pages/index.ets @@ -0,0 +1,17 @@ +@Entry +@Component +struct Index { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Button() { + Text('This is ability2 index page') + .fontSize(25) + .fontWeight(FontWeight.Medium) + .margin({left:20,right:20}) + } + .padding({ top: 20, left: 20, right: 20, bottom: 20 }) + } + .width('100%') + .height('100%') + } +} \ No newline at end of file diff --git a/Ability/PageAbility/entry/src/main/ets/MainAbility2/pages/second.ets b/Ability/PageAbility/entry/src/main/ets/MainAbility2/pages/second.ets new file mode 100644 index 0000000000000000000000000000000000000000..89c5915373e0314f03c6df8fd99fcb71c130d58b --- /dev/null +++ b/Ability/PageAbility/entry/src/main/ets/MainAbility2/pages/second.ets @@ -0,0 +1,17 @@ +@Entry +@Component +struct Second { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Button() { + Text('This is ability2 second page') + .fontSize(25) + .fontWeight(FontWeight.Medium) + .margin({left:20,right:20}) + } + .padding({ top: 20, left: 20, right: 20, bottom: 20 }) + } + .width('100%') + .height('100%') + } +} \ No newline at end of file diff --git a/Ability/PageAbility/entry/src/main/resources/base/element/string.json b/Ability/PageAbility/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..edd8e4399a76d10c88dd2e9018baab8b5672d33b --- /dev/null +++ b/Ability/PageAbility/entry/src/main/resources/base/element/string.json @@ -0,0 +1,20 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "entry_MainAbility" + }, + { + "name": "description_mainability", + "value": "ETS_Empty Ability" + }, + { + "name": "description_mainability2", + "value": "ETS_Empty Ability" + }, + { + "name": "entry_MainAbility2", + "value": "entry_MainAbility2" + } + ] +} \ No newline at end of file diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/icon.png b/Ability/PageAbility/entry/src/main/resources/base/media/icon.png similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/common/images/icon.png rename to Ability/PageAbility/entry/src/main/resources/base/media/icon.png diff --git a/Ability/PageAbility/figures/zh-cn_image_0000001188791474.png b/Ability/PageAbility/figures/zh-cn_image_0000001188791474.png new file mode 100644 index 0000000000000000000000000000000000000000..5600b26e2f3ec00b50ef85ea2ee1b9e82e7f1133 Binary files /dev/null and b/Ability/PageAbility/figures/zh-cn_image_0000001188791474.png differ diff --git a/Ability/PageAbility/figures/zh-cn_image_0000001189113124.png b/Ability/PageAbility/figures/zh-cn_image_0000001189113124.png new file mode 100644 index 0000000000000000000000000000000000000000..cf1049e7bc35cbb07a38b056a42934c48299a668 Binary files /dev/null and b/Ability/PageAbility/figures/zh-cn_image_0000001189113124.png differ diff --git a/Ability/PageAbility/figures/zh-cn_image_0000001234154343.png b/Ability/PageAbility/figures/zh-cn_image_0000001234154343.png new file mode 100644 index 0000000000000000000000000000000000000000..8d5e7c942e75c66d39c557346bb92aa9f72228f9 Binary files /dev/null and b/Ability/PageAbility/figures/zh-cn_image_0000001234154343.png differ diff --git a/Ability/PageAbility/figures/zh-cn_image_0000001234372249.png b/Ability/PageAbility/figures/zh-cn_image_0000001234372249.png new file mode 100644 index 0000000000000000000000000000000000000000..84be09d22aef5ba00f9064fb6e7fddad411f8382 Binary files /dev/null and b/Ability/PageAbility/figures/zh-cn_image_0000001234372249.png differ diff --git "a/Ability/PageAbility/figures/\345\217\226\347\211\210\346\234\254.png" "b/Ability/PageAbility/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/Ability/PageAbility/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/Ability/PageAbility/figures/\346\210\252\345\233\276.png" "b/Ability/PageAbility/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/Ability/PageAbility/figures/\346\210\252\345\233\276.png" differ diff --git a/Ability/PageAbility/gradle/wrapper/gradle-wrapper.jar b/Ability/PageAbility/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9 Binary files /dev/null and b/Ability/PageAbility/gradle/wrapper/gradle-wrapper.jar differ diff --git a/Ability/PageAbility/gradle/wrapper/gradle-wrapper.properties b/Ability/PageAbility/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..f59159e865d4b59feb1b8c44b001f62fc5d58df4 --- /dev/null +++ b/Ability/PageAbility/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/Ability/PageAbility/public_sys-resources/icon-caution.gif b/Ability/PageAbility/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Ability/PageAbility/public_sys-resources/icon-caution.gif differ diff --git a/Ability/PageAbility/public_sys-resources/icon-danger.gif b/Ability/PageAbility/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Ability/PageAbility/public_sys-resources/icon-danger.gif differ diff --git a/Ability/PageAbility/public_sys-resources/icon-note.gif b/Ability/PageAbility/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/Ability/PageAbility/public_sys-resources/icon-note.gif differ diff --git a/Ability/PageAbility/public_sys-resources/icon-notice.gif b/Ability/PageAbility/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/Ability/PageAbility/public_sys-resources/icon-notice.gif differ diff --git a/Ability/PageAbility/public_sys-resources/icon-tip.gif b/Ability/PageAbility/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/Ability/PageAbility/public_sys-resources/icon-tip.gif differ diff --git a/Ability/PageAbility/public_sys-resources/icon-warning.gif b/Ability/PageAbility/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Ability/PageAbility/public_sys-resources/icon-warning.gif differ diff --git a/Ability/PageAbility/settings.gradle b/Ability/PageAbility/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07 --- /dev/null +++ b/Ability/PageAbility/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/Data/Database/README.md b/Data/Database/README.md index e12613c597b8ae02ff68662c00742eae4c374a43..4c78481f490197320f1ae63a636e7d971af2c54f 100644 --- a/Data/Database/README.md +++ b/Data/Database/README.md @@ -1,4 +1,485 @@ -#Database +# 1.介绍 -简介 • JSUI轻量级存储为应用提供key-value键值型的文件数据处理能力,支持应用对数据进行轻量级存储及查询。数据存储形式为键值对, -键的类型为字符串型,本示例用于展示轻量级存储的实现。 \ No newline at end of file +OpenHarmony在数据管理模块中提供了轻量级存储的能力。轻量级存储为应用提供key-value键值型的文件数据处理能力,支持应用对数据进行轻量级存储及查询。数据存储形式为键值对,键的类型为字符串型,值的存储数据类型包括数字型、字符型、布尔型。本篇Codelab将介绍基于JS扩展的类Web开发范式的轻量级数据库的创建、数据的增加/删除/修改/查询等操作方法,让您快速了解轻量级存储能力并能够实现数据存储。效果图如下: + +![](figures/IMG_20211216_173309.jpg) + +# 2.相关概念 + +[轻量级存储](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-data-storage.md) + +# 3.搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + + + +# 4.任务一:完成页面布局 + +1. 设置标题。 + + ``` +
+
+ DataBase +
+
+ ``` + +2. 添加键值对列表表头。 + + ``` +
+ ... + + +
+ + +
+
+
+ + KEY + +
+
+ + VALUE + +
+
+
+
+
+
+
+
+
+ + ``` + + 整体效果如下: + + ![](figures/aa.png) + +3. 添加键值对列表。 + + ``` + + +
+ + ... + +
+
+
+ + {{ obj.KEY}} + +
+
+ + {{ obj.VALUE}} + +
+
+
+
+
+
+
+
+ ``` + + 整体效果如下: + + ![](figures/IMG_20211221_181219.png) + +4. 添加key、value的输入框。 + + ``` +
+ ... +
+ +
+ +
+
+
+ +
+ +
+
+
+ ``` + + 效果如下: + + ![](figures/a2.png) + +5. 添加增加、查询、删除以及删除数据库的按钮。 + + ``` +
+ ... +
+ + + + +
+
+ ``` + + 效果如下: + + ![](figures/a3.png) + +# 5.任务二:为页面设计样式 + +此任务定义了整个页面中各个组件的样式,相关css更多的知识可以参考[css语法参考](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-framework-syntax-css.md)。在index.css中添加如下代码: + +``` +.container { + flex-direction: column; + align-items: center; +} +.div_row { + width: 100%; + flex-direction: row; +} +.div_title { + width: 100%; + justify-content: center; + margin-top: 20px; + margin-bottom: 20px; +} +.text_title { + font-size: 30px; + color: #000000; +} +.row { + width: 98%; + margin-top: 5px; + flex-direction: row; +} +.input-block { + width: 100%; +} +.label { + font-size: 20px; + width: 120px; + text-align: right; +} +.input { + width: 90%; + font-size: 15px; +} +.button { + margin-top: 70px; + margin-left: 10px; + margin-right: 10px; + width: 150px; + background-color: #17A98E; +} +.button-delete { + margin-top: 70px; + margin-left: 10px; + margin-right: 10px; + width: 150px; + background-color: #DE1A33; +} +.title { + font-size: 40px; + color: #000000; + opacity: 0.9; +} +.tag-list { + width: 100%; +} +.todo-list-item { + width: 100%; + justify-content: center; + flex-direction: row; +} +.todo-item { + height: 120px; + width: 100%; + border-radius: 5px; + align-items: center; + flex-direction: row; +} +.flex-row { + flex-direction: row; + align-item: center; +} +.todo-name { + font-size: 32px; + color: white; + height: 100px; + margin-right: 5px; + max-lines: 1; + text-overflow: ellipsis; +} +.div_list_title { + width: 100%; + flex-direction: row; +} +.div_list_title_ROW { + width: 50%; + align-items: center; +} +.text_list_title { + width: 100%; + text-align: center; +} +.list-item-block { + width: 98%; + margin-top: 2px; + border-radius: 5px; + background-color: white; + flex-direction: row; /* 子元素横向排列 */ + display: flex; +} +.describe { + flex-direction: column; + align-items: flex-start; /* 元素位于容器开头 */ + margin-left: 5px; + width: 210px; +} +.describe-text { + margin-top: 5px; + font-size: 20px;} +.text-default { + color: white; +} +.text-gray { + color: gray; +} +.todo-mark { + width: 18px; + height: 30%; + margin-left: 16px; + border-radius: 50px; + background-color: lightslategrey; +} +.todo-text-wrapper { + height: 100%; + flex-grow: 1; + margin: 0px 32px; + flex-direction: column; +} +.todo-name-mark { + width: 100%; + height: 100%; + align-items: center; +} +@media screen and (device-type: tablet) and (orientation: landscape) { + .title { + font-size: 100px; + } +} +@media screen and (device-type: wearable) { + .title { + font-size: 28px; + color: #FFFFFF; + } +} +@media screen and (device-type: tv) { + .container { + background-image: url("../../common/images/Wallpaper.png"); + background-size: cover; + background-repeat: no-repeat; + background-position: center; + } + .title { + font-size: 100px; + color: #FFFFFF; + } +} +@media screen and (device-type: phone) and (orientation: landscape) { + .title { + font-size: 60px; + } +} +#table { + width: 100%; + height: 500px; +} +.row1 { + display: flex ; + flex-direction:row; +} +.col1 { + width: 100%; + height: 40px; + border: 0.5px solid #000; +} +.col-content { + width: 100%; + height: 40px; + border-left: 0.5px solid #000; + border-right: 0.5px solid #000; + border-bottom: 0.5px solid #000; +} +``` + +# 6.任务三:为组件设置相应的事件 + +1. 初始化数据设置。 + + ``` + data: { + // 索引键值 + key: '', + // 数据 + value: '', + // 数据库的数据,以数组形式保存 + tableData: [ + ], + defaultResult: 'Not found', + path: '' + }, + // 初始化方法,本示例在这这个方法中设置了数据表的存放路径 + async onInit() { + var context = featureAbility.getContext() + this.path = await context.getFilesDir() + '/mystore' + dataStorage.deleteStorageSync(this.path); + } + } + ``` + +2. 为添加数据的按钮绑定添加数据事件。 + + 设置添加数据的事件: + + ``` + + ``` + + 编写添加数据的方法: + + ``` + buttonClickAdd() { + if (this.key !== '' && this.value !== '') { + const store = dataStorage.getStorageSync(this.path); + const ret = store.getSync(this.key, this.defaultResult); + const data = store.putSync(this.key, this.value); + store.flushSync(); + if (ret === this.defaultResult) { + this.showPrompt('Add Success!'); + this.tableData.push({KEY: this.key, VALUE: this.value}); + } else { + this.tableData = this.tableData.filter(item => item.KEY !== this.key); + this.tableData.push({KEY: this.key, VALUE: this.value}); + this.showPrompt('Update!'); + } + } else { + this.showPrompt('Key or value is Empty!'); + } + } + ``` + +3. 为查询数据按钮设置查询数据的事件。 + + 设置添查询数据的事件: + + ``` + + ``` + + 编写查询数据的方法: + + ``` + buttonClickQuery() { + if (this.key !== '') { + const store = dataStorage.getStorageSync(this.path); + const ret = store.getSync(this.key, this.defaultResult); + this.showPrompt(ret); + } else { + this.showPrompt('Key is Empty!'); + } + } + ``` + +4. 为删除单条数据按钮设置删除单条数据的事件。 + + 设置删除单条数据的事件: + + ``` + + ``` + + 编写删除单条数据的方法: + + ``` + buttonClickDel() { + if (this.key !== '') { + const store = dataStorage.getStorageSync(this.path); + const ret = store.hasSync(this.key); + if (ret) { + store.deleteSync(this.key); + this.tableData = this.tableData.filter(item => item.KEY !== this.key); + this.showPrompt('Del Sucess'); + } else { + this.showPrompt('Error, The KEY is not exist'); + } + } else { + this.showPrompt('Error, The KEY is Empty!'); + } + } + ``` + +5. 为删除数据库按钮设置删除数据库的事件。 + + 1. 定义删除数据库的按钮,并绑定事件: + + ``` + + ``` + + 2. 编写删除数据库的方法: + + ``` + buttonClickDelDatabase() { + dataStorage.deleteStorageSync(this.path); + this.tableData = []; + this.showPrompt('database is delete!'); + } + ``` + +# 7.恭喜你 + +您已经成功地学习了如何通过dataStorage创建轻量级偏好数据库,并实现数据库表格数据的增加、删除、查询以及删除数据库的功能。 + +# 8.参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/Data/Database) \ No newline at end of file diff --git a/Data/Database/entry/src/main/js/default/pages/index/index.js b/Data/Database/entry/src/main/js/default/pages/index/index.js index 8dc939c4d26bd571fc4dba9e743f8fa3a6877d62..12c85400da66e4e15b57bff8d918cc8592cbaff1 100644 --- a/Data/Database/entry/src/main/js/default/pages/index/index.js +++ b/Data/Database/entry/src/main/js/default/pages/index/index.js @@ -14,20 +14,22 @@ */ import prompt from '@system.prompt'; -import data_storage from '@ohos.data.storage'; +import dataStorage from '@ohos.data.storage'; +import featureAbility from '@ohos.ability.featureAbility' export default { data: { - title: '', key: '', value: '', tableData: [ ], defaultResult: 'Not found', - path: '/data/accounts/account_0/appdata/com.huawei.cookbook/pdb' + path: '' }, - onInit() { - data_storage.deleteStorageSync(this.path); + async onInit() { + var context = featureAbility.getContext() + this.path = await context.getFilesDir() + '/mystore' + dataStorage.deleteStorageSync(this.path); }, // 文本框内容发生变化 @@ -43,7 +45,7 @@ export default { // 提交 buttonClickAdd() { if (this.key !== '' && this.value !== '') { - const store = data_storage.getStorageSync(this.path); + const store = dataStorage.getStorageSync(this.path); const ret = store.getSync(this.key, this.defaultResult); const data = store.putSync(this.key, this.value); store.flushSync(); @@ -62,7 +64,7 @@ export default { buttonClickQuery() { if (this.key !== '') { - const store = data_storage.getStorageSync(this.path); + const store = dataStorage.getStorageSync(this.path); const ret = store.getSync(this.key, this.defaultResult); this.showPrompt(ret); } else { @@ -72,7 +74,7 @@ export default { buttonClickDel() { if (this.key !== '') { - const store = data_storage.getStorageSync(this.path); + const store = dataStorage.getStorageSync(this.path); const ret = store.hasSync(this.key); if (ret) { store.deleteSync(this.key); @@ -86,7 +88,7 @@ export default { } }, buttonClickDelDatabase() { - data_storage.deleteStorageSync(this.path); + dataStorage.deleteStorageSync(this.path); this.tableData = []; this.showPrompt('database is delete!'); }, diff --git a/Data/Database/figures/IMG_20211216_173309.jpg b/Data/Database/figures/IMG_20211216_173309.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ac62d51b3f605c5dfbbb6400a65269a6d3767cc4 Binary files /dev/null and b/Data/Database/figures/IMG_20211216_173309.jpg differ diff --git a/Data/Database/figures/IMG_20211221_181219.png b/Data/Database/figures/IMG_20211221_181219.png new file mode 100644 index 0000000000000000000000000000000000000000..f8fe5f50e1f9e94ca08dec659e5d622d089cdeda Binary files /dev/null and b/Data/Database/figures/IMG_20211221_181219.png differ diff --git a/Data/Database/figures/a2.png b/Data/Database/figures/a2.png new file mode 100644 index 0000000000000000000000000000000000000000..3b9acdce7f5efec34257d61088d148db1440b27c Binary files /dev/null and b/Data/Database/figures/a2.png differ diff --git a/Data/Database/figures/a3.png b/Data/Database/figures/a3.png new file mode 100644 index 0000000000000000000000000000000000000000..5a2c3441931d1fbaa8f8a3066213a76bbaaec9f4 Binary files /dev/null and b/Data/Database/figures/a3.png differ diff --git a/Data/Database/figures/aa.png b/Data/Database/figures/aa.png new file mode 100644 index 0000000000000000000000000000000000000000..a04b40ce7c75fceddc0b3da71dd0d2cfbc8097e7 Binary files /dev/null and b/Data/Database/figures/aa.png differ diff --git "a/Data/Database/figures/\345\217\226\347\211\210\346\234\254.png" "b/Data/Database/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/Data/Database/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/Data/Database/figures/\346\210\252\345\233\276.png" "b/Data/Database/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/Data/Database/figures/\346\210\252\345\233\276.png" differ diff --git a/Data/Database/public_sys-resources/icon-caution.gif b/Data/Database/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Data/Database/public_sys-resources/icon-caution.gif differ diff --git a/Data/Database/public_sys-resources/icon-danger.gif b/Data/Database/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Data/Database/public_sys-resources/icon-danger.gif differ diff --git a/Data/Database/public_sys-resources/icon-note.gif b/Data/Database/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/Data/Database/public_sys-resources/icon-note.gif differ diff --git a/Data/Database/public_sys-resources/icon-notice.gif b/Data/Database/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/Data/Database/public_sys-resources/icon-notice.gif differ diff --git a/Data/Database/public_sys-resources/icon-tip.gif b/Data/Database/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/Data/Database/public_sys-resources/icon-tip.gif differ diff --git a/Data/Database/public_sys-resources/icon-warning.gif b/Data/Database/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Data/Database/public_sys-resources/icon-warning.gif differ diff --git a/Data/JSRelationshipData/README.md b/Data/JSRelationshipData/README.md index ba71f3696bd134e955b8e681bdfbe3537945aa1e..22a5f797caf0b77dc74f13f2093acfd19f246698 100644 --- a/Data/JSRelationshipData/README.md +++ b/Data/JSRelationshipData/README.md @@ -1,6 +1,157 @@ -JSRelationshipData -本篇Codelab是在HarmonyOS 关系型数据库(JAVA)的设计基础上,用JS编程语言重写了一个布局一模一样的关系型数据库,并对OpenHarmony开发板进行了适配。 +# 介绍 + +本篇Codelab介绍数据库的创建、数据的增加/删除/修改/查询等操作方法,让您快速了解关系型数据管理能力并能够开发数据库相关应用服务。效果图如下:![](figures/zh-cn_image_0000001188327086.png) + +# 搭建OpenHarmony环境 +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 导入模块 + +在JS文件中导入关系型数据库所需的模块。 + +``` +import ohos_data_rdb from '@ohos.data.rdb' +``` + +# 创建关系型数据库 + +参考关系型数据库[接口](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-data-rdb.md),在kvStoreModel类中定义RdbStore变量,并通过getRdbStore创建数据库RdbTest.db及表employee,示例代码如下: + +``` +import ohos_data_rdb from '@ohos.data.rdb' +const STORE_CONFIG = { name: "RdbTest.db" } +const SQL_CREATE_TABLE = "CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, AGE INTEGER, GENDER TEXT NOT NULL)" +export default class KvStoreModel { + rdbStore; + createKvStore(callback) { + if (typeof (this.rdbStore) === 'undefined') { + let self = this; + let promise = ohos_data_rdb.getRdbStore(STORE_CONFIG, 1) + promise.then(async (rdbStore) => {… + self.rdbStore = rdbStore; + await rdbStore.executeSql(SQL_CREATE_TABLE, null); + console.info("rdbStore" + 'create table done.') + callback(); + }).catch((err) => { + console.info("kvStore" + err) + callback(); + }) + }else { + callback(); + } + } +} +``` + +# 数据库操作方法 +创建关系型数据库后,获得一个RdbStore,通过RdbStore调用相关接口执行相关的数据操作,结果以Promise形式返回。 + +- 查询数据库:使用query\(\)方法,该方法接收返回函数callback。其中,查询的条件predicates 由RdbPredicates的实例对象指定。columns 表示要查询的列,如果查询的列为空,则查询所有的列。根据查询条件和传入的列名查询数据库的示例代码如下: + + ``` + query(callback) { + this.createKvStore(() => { + var contactList = [] + //查询的条件 + let predicates = new ohos_data_rdb.RdbPredicates("EMPLOYEE") + let columns = ["ID", "NAME", "AGE", "GENDER"] + let promise = this.rdbStore.query(predicates,columns) + console.log("rdbStore query start") + promise.then((resultSet) => { + if (resultSet.rowCount > 0) { + while (resultSet.goToNextRow()) { + //返回 + let id = resultSet.getLong(resultSet.getColumnIndex("ID")); + + let userName = resultSet.getString(resultSet.getColumnIndex("NAME")); + let userAge = resultSet.getLong(resultSet.getColumnIndex("AGE")); + let userGender = resultSet.getLong(resultSet.getColumnIndex("GENDER")); + const obj = { + id:id,name:userName,age:userAge,gender:userGender + }; + contactList.push(obj); + } + } + resultSet.close(); + resultSet = null; + callback(contactList); + console.log("resultSet column names:" + resultSet.columnNames) + console.log("resultSet column count:" + resultSet.columnCount)} + ) + }) + } + ``` + +- 新增数据:使用insert\(\)方法,该方法接受两个参数,分别是要插入的表名和要插入到表中的数据行。其中,插入的数据由valueBucket封装,服务端可以从该参数中解析出对应的属性,然后插入到数据库中。该方法结果以Promise形式返回。如果操作成功,返回行ID,否则返回-1。 + + ``` + insert(name,valueBucket) { + console.info('rdbStore.insert ' +valueBucket[0].name+"---"+valueBucket[0].gender); + let promise = this.rdbStore.insert(name, valueBucket) + promise.then(async (rows) => { + await console.log("rdbStore.insert first done: " + rows) + }).catch((err) => {}) + } + ``` + +- 更新数据:使用update\(\)方法,该方法接受两个参数,分别是插入到表中要更新的数据行和插入到表中的数据行。其中,插入到表中要更新的数据行由[ValuesBucket](https://gitee.com/openharmony/docs/tree/master/zh-cn/application-dev/reference)封装,插入到表中的数据行由rdbPredicates的实例对象指定。该方法结果以Promise形式返回。如果操作成功,返回行ID,否则返回-1。 + + ``` + update(valueBucket,index){ + console.info('rdbStore.update ' +index+"=="+valueBucket); + let predicates = new ohos_data_rdb.RdbPredicates("EMPLOYEE"); + predicates.equalTo("ID", index); + let promise = this.rdbStore.update(valueBucket, predicates) + promise.then(async (ret) => { + await console.log("rdbStore.update updated row count: " + rows) + }).catch((err) => {}) + } + ``` + +- 删除数据:使用delete\(\)方法,该方法需要传入需要删除的数据行。其中,删除的数据行由rdbPredicates的实例对象指定。该方法结果以Promise形式返回。如果操作成功,返回行ID,否则返回-1。 + + ``` + delete(index) { + console.info('rdbStore.delete ' +index); + let predicates = new ohos_data_rdb.RdbPredicates("EMPLOYEE"); + predicates.equalTo("ID", index); + this.rdbStore.delete(predicates, function (err, rows) { + console.log("rdbStore.delete rows: " + rows)}) + } + ``` + +# 恭喜你 + +您已经成功地学习了如何通过getRdbStore创建关系型数据库,并提供数据库表格数据的增、删、改、查API接口。 + +# 参考 +代码待开源 + + + -Java版本的分布式数据库教会了大家使用关系型数据库,实现增删改查基本功能。 -本篇Codelab将使用JS语言进行开发,做一个功能、布局和Java版本完全一样的关系型数据库,大家可以通过这两篇Codelab学习两种编程语言的编码风格和实现区别。 \ No newline at end of file diff --git a/Data/JSRelationshipData/entry/src/main/js/MainAbility/pages/index/index.js b/Data/JSRelationshipData/entry/src/main/js/MainAbility/pages/index/index.js index b9eafc6aadb93d42dcff1f8434545400ec34639d..ce99d75adc639188ed4e8b7310d11ef66ce0b2f6 100644 --- a/Data/JSRelationshipData/entry/src/main/js/MainAbility/pages/index/index.js +++ b/Data/JSRelationshipData/entry/src/main/js/MainAbility/pages/index/index.js @@ -43,7 +43,6 @@ export default { this.contactList = contactList; } }); - //this.showDialog(); }, // 展示添加或编辑信息弹窗 showDialog() { @@ -57,24 +56,43 @@ export default { this.$element('addDialog').close(); }, confirmClick() { - if (this.dialogTitle === '添加信息') { - const obj = { - name: this.name,age:this.nameAge,gender:this.gender - }; - this.contactList.push(obj); - this.kvStoreModel.insertValue(obj); + if (!this.checkInput()) { + return; + } + if (this.dialogTitle === '添加信息') { + const obj = { + name: this.name,age:this.nameAge,gender:this.gender + }; + this.contactList.push(obj); + this.kvStoreModel.insertValue(obj); + } else { + this.contactList[this.listIndex].name = this.name; + this.contactList[this.listIndex].age = this.nameAge; + this.contactList[this.listIndex].gender = this.gender; + const obj = { + name: this.name,age:this.nameAge,gender:this.gender + }; + this.kvStoreModel.updateValue(obj,this.id); + } + this.cancelDialog(); + this.queryContact(); + }, + + checkInput() { + if (this.name === '' || this.name.trim() === '') { + this.showErrorMessage('name', '姓名不能为空'); + return false; + } else if (this.nameAge === '' || this.nameAge.trim() === '') { + this.showErrorMessage('nameAge', '年龄不能为空'); + return false; + } else if (this.gender === '' || this.gender.trim() === '') { + this.showErrorMessage('gender', '性别不能为空'); + return false; } else { - this.contactList[this.listIndex].name = this.name; - this.contactList[this.listIndex].age = this.nameAge; - this.contactList[this.listIndex].gender = this.gender; - const obj = { - name: this.name,age:this.nameAge,gender:this.gender - }; - this.kvStoreModel.updateValue(obj,this.id); + return true; } - this.queryContact(); - this.cancelDialog(); }, + changeName(e) { this.name = e.value; }, diff --git a/Data/JSRelationshipData/figures/zh-cn_image_0000001188327086.png b/Data/JSRelationshipData/figures/zh-cn_image_0000001188327086.png new file mode 100644 index 0000000000000000000000000000000000000000..3378b397dfdf33adcc5ee420ec3e567e23532c71 Binary files /dev/null and b/Data/JSRelationshipData/figures/zh-cn_image_0000001188327086.png differ diff --git a/Data/JSRelationshipData/figures/zh-cn_image_0000001192238726.png b/Data/JSRelationshipData/figures/zh-cn_image_0000001192238726.png new file mode 100644 index 0000000000000000000000000000000000000000..d04f1b3bead6d596f3d166dca87bece6614bffea Binary files /dev/null and b/Data/JSRelationshipData/figures/zh-cn_image_0000001192238726.png differ diff --git "a/Data/JSRelationshipData/figures/\345\217\226\347\211\210\346\234\254.png" "b/Data/JSRelationshipData/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/Data/JSRelationshipData/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/Data/JSRelationshipData/figures/\346\210\252\345\233\276.png" "b/Data/JSRelationshipData/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/Data/JSRelationshipData/figures/\346\210\252\345\233\276.png" differ diff --git a/Data/JSRelationshipData/public_sys-resources/icon-caution.gif b/Data/JSRelationshipData/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Data/JSRelationshipData/public_sys-resources/icon-caution.gif differ diff --git a/Data/JSRelationshipData/public_sys-resources/icon-danger.gif b/Data/JSRelationshipData/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Data/JSRelationshipData/public_sys-resources/icon-danger.gif differ diff --git a/Data/JSRelationshipData/public_sys-resources/icon-note.gif b/Data/JSRelationshipData/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/Data/JSRelationshipData/public_sys-resources/icon-note.gif differ diff --git a/Data/JSRelationshipData/public_sys-resources/icon-notice.gif b/Data/JSRelationshipData/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/Data/JSRelationshipData/public_sys-resources/icon-notice.gif differ diff --git a/Data/JSRelationshipData/public_sys-resources/icon-tip.gif b/Data/JSRelationshipData/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/Data/JSRelationshipData/public_sys-resources/icon-tip.gif differ diff --git a/Data/JSRelationshipData/public_sys-resources/icon-warning.gif b/Data/JSRelationshipData/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Data/JSRelationshipData/public_sys-resources/icon-warning.gif differ diff --git a/Data/JsDistributedData/README.md b/Data/JsDistributedData/README.md index a16ef653a0305d725d70c8b0800b1060c006c916..c69971bc7040f2f4221031ab8c4a7e7f74c1fbf9 100644 --- a/Data/JsDistributedData/README.md +++ b/Data/JsDistributedData/README.md @@ -1,7 +1,216 @@ -# JsDistributedData +# 介绍 + +分布式数据服务\(Distributed Data Service,DDS\)为应用程序提供不同设备间数据分布式的能力。通过调用分布式数据接口,应用程序将数据保存到分布式数据库中。通过结合帐号、应用和分布式数据服务对属于不同的应用的数据进行隔离,保证不同应用之间的数据不能通过分布式数据服务互相访问。在通过可信认证的设备间,分布式数据服务支持应用数据相互同步,为用户提供在多种终端设备上一致的数据访问体验。效果图如下: + +**图 1** +![](figures/zh-cn_image_0000001189809642.gif "zh-cn_image_0000001189809642") + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 代码结构解读 + +本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在最后的参考中提供下载方式,接下来我们来讲解整个工程的代码结构: + +![](figures/zh-cn_image_0000001237668963.png) + +- pages:用于存放所有页面的目录。 + - index:构成关系型数据库操作界面,包括index.hml布局文件,index.css样式文件,index.js逻辑处理文件。 + - KvStoreModel.js:创建分布式数据库,以及提供表格数据的增、删、改、查API接口。 + + +- config.json:配置文件。 + +# 分布式组网 + +1. 硬件准备:准备两台烧录相同的版本系统的**Hi3516DV300**开发板A,B。 +2. 两个开发板A,B配置在同一个WiFi网络之下。 + + 打开设置--\>WLAN--\>点击右侧WiFi开关--\>点击目标WiFi并输入密码。 + + ![](figures/IMG_20211217_144057.jpg) + +3. 将设备A,B设置为互相信任的设备。 + + - 找到系统应用“音乐”。 + + ![](figures/音乐.png) + + - 设备A打开音乐,点击左下角流转按钮,弹出列表框,在列表中会展示远端设备的id。 + + ![](figures/IMG_20211213_103011.jpg) + + - 选择远端设备B的id,另一台开发板(设备B)会弹出验证的选项框。 + + ![](figures/信.png) + + - 设备B点击允许,设备B将会弹出随机PIN码,将设备B的PIN码输入到设备A的PIN码填入框中。 + + ![](figures/pin.png)![](figures/确认.png) + + 配网完毕。 + +# 创建分布式数据库 + +1. 导入模块 + + ``` + import distributedData from '@ohos.data.distributeddata'; + ``` + +2. 参考分布式数据库[接口](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-distributed-data.md),在kvStoreModel类中定义KvManager和KvStore变量,并通过createKVManager创建分布式数据库管理对象KvManager,通过getKVStore获取数据库操作实例KvStore。其中config表示创建KVManager实例的配置信息,包括调用方的包名和用户信息。options表示创建 KvStore实例的配置信息。表示示例代码如下: + +``` +export default class KvStoreModel { + kvManager; + kvStore; + constructor() { + } + createKvStore(callback) { + if (typeof (this.kvStore) === 'undefined') { + //创建KVManager实例的配置信息 + var config = { + bundleName: 'com.ohos.distributedmusicplayer', + userInfo: { + userId: '0', + userType: 0 + } + }; + let self = this; + distributedData.createKVManager(config).then((manager) => { + self.kvManager = manager; + //创建 KvStore实例的配置信息 + var options = { + createIfMissing: true, + encrypt: false, + backup: false, + autoSync: true, + kvStoreType: 1, + schema: '', + securityLevel: 3, + }; + self.kvManager.getKVStore(STORE_ID, options).then((store) => { + self.kvStore = store; + callback(); + }); + }); + } else { + callback(); + } + } +} +``` + +# 操作分布式数据方法 + +创建分布式数据库后,获得一个KvStore,通过KvStore调用相关接口执行相关的数据操作,结果以Promise形式返回。 + +- 添加键值对到数据库:使用put\(\)方法,该方法接收两个参数,分别是要添加的数值Key和要添加的数值。示例代码如下: + + ``` + put(key, value) { + this.kvStore.put(key, value).then((data) => { + this.kvStore.get(key).then((data) => { + }); + }).catch((err) => { + }); + } + ``` + +- 数据库中删除指定键值对的数据:使用delete\(\)方法,该方法接收一个参数,需要删除数据的键值key,结果以Promise形式返回。示例代码如下: + + ``` + delete(key) { + this.kvStore.delete(key).then((data) => { + }).catch((err) => { + }); + } + ``` + +- 数据库中获取指定键值对的数据:使用get\(\)方法,该方法接收两个参数,分别是需要获取数据的键值key和返回函数callback,结果以callback函数形式返回。示例代码如下: + + ``` + get(key,callback){ + this.kvStore.get(key).then((data) => { + callback(data); + }); + } + ``` + +# 同步分布式数据库 + +通常情况下,当数据库的数据产生变化时,需要主动通知与该数据相关联的进程或者应用,从而使得相关进程或者应用接收到数据变化后完成相应的处理。对于数据提供方,当数据库数据变化,可以通过如下方法通知数据订阅者: + +``` +broadcastMessage(key, value) { + let self = this; + this.createKvStore(() => { + self.put(key, value);//self.delete(key)新增或者删除数据都可导致数据变化 + }); +} +``` + +对于数据接收方,可以通过KvStore提供的[on](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/Readme-CN.md)方法注册一个数据订阅者。示例代码如下: + +``` +setOnMessageReceivedListener(callback) { + let self = this; + this.createKvStore(() => { + self.kvStore.on('dataChange', 1, (data) => { + for (var i = 0; i < data.insertEntries.length; i++) { + callback(data.insertEntries[0].key, data.insertEntries[0].value.value, 0); + return; + } + for (i = 0; i < data.updateEntries.length; i++) { + callback(data.updateEntries[0].key, data.updateEntries[0].value.value, 1); + return; + } + for (i = 0; i < data.deleteEntries.length; i++) { + callback(data.deleteEntries[0].key, '', 2); + return; + } + }); + }); +} +``` +# 恭喜你 + +通过本Codelab的学习,您已经学会了分布式数据库服务的基础操作(创建、新增、删除、同步)。 + +# 参考 + +代码待开源 + + + + + + -本篇Codelab是在HarmonyOS 分布式数据库(JAVA)的设计基础上,用JS编程语言重写了一个布局一模一样的分布式数据库,并对OpenHarmony开发板进行了适配。 -Java版本的分布式数据库教会了大家通过分布式数据接口,实现多种设备上一致的数据访问体验。 -本篇Codelab将使用JS语言进行开发,做一个功能、布局和Java版本完全一样的分布式数据库,大家可以通过这两篇Codelab学习两种编程语言的编码风格和实现区别。 \ No newline at end of file diff --git a/Data/JsDistributedData/build.gradle b/Data/JsDistributedData/build.gradle index f352cdeb1daf5634a46e3018408e6bfbf24bb47f..d79190c37ffeb7dbfd62e82f424bd0c401e95c72 100644 --- a/Data/JsDistributedData/build.gradle +++ b/Data/JsDistributedData/build.gradle @@ -3,66 +3,32 @@ apply plugin: 'com.huawei.ohos.app' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 + supportSystem "standard" } - + buildscript { repositories { maven { -<<<<<<< HEAD -<<<<<<< HEAD - url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/' -======= url 'https://repo.huaweicloud.com/repository/maven/' ->>>>>>> a7fd881db71f93f9ba2923fc2ed13ab77577dd33 } maven { url 'https://developer.huawei.com/repo/' } } dependencies { -<<<<<<< HEAD classpath 'com.huawei.ohos:hap:3.0.3.2' - classpath 'com.huawei.ohos:decctest:3.0.1.0' -======= - url 'https://repo.huaweicloud.com/repository/maven/' - } - maven { - url 'https://developer.huawei.com/repo/' - } - } - dependencies { - classpath 'com.huawei.ohos:hap:2.4.5.5' - classpath 'com.huawei.ohos:decctest:1.2.5.1' ->>>>>>> 0e50d605db36ff6e317e21b849a5220bed711ca3 -======= - classpath 'com.huawei.ohos:hap:2.4.5.5' - classpath 'com.huawei.ohos:decctest:1.2.5.1' ->>>>>>> a7fd881db71f93f9ba2923fc2ed13ab77577dd33 + classpath 'com.huawei.ohos:decctest:1.2.6.0' } } allprojects { repositories { maven { -<<<<<<< HEAD -<<<<<<< HEAD - url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/' - } - maven { - url 'http://mirrors.tools.huawei.com/maven/' -======= - url 'https://repo.huaweicloud.com/repository/maven/' - } - maven { - url 'https://developer.huawei.com/repo/' ->>>>>>> 0e50d605db36ff6e317e21b849a5220bed711ca3 -======= url 'https://repo.huaweicloud.com/repository/maven/' } maven { url 'https://developer.huawei.com/repo/' ->>>>>>> a7fd881db71f93f9ba2923fc2ed13ab77577dd33 } } } diff --git a/Data/JsDistributedData/entry/build.gradle b/Data/JsDistributedData/entry/build.gradle index eceab3513074876287dccf2eb0a4133bec98f49c..68ec4e15705e1c4fd6ca07fe7ad0444a86546c7a 100644 --- a/Data/JsDistributedData/entry/build.gradle +++ b/Data/JsDistributedData/entry/build.gradle @@ -1,25 +1,9 @@ apply plugin: 'com.huawei.ohos.hap' -<<<<<<< HEAD -<<<<<<< HEAD -apply plugin: 'com.huawei.ohos.decctest' -======= ->>>>>>> a7fd881db71f93f9ba2923fc2ed13ab77577dd33 //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { compileSdkVersion 7 defaultConfig { -<<<<<<< HEAD - compatibleSdkVersion 6 -======= -//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 -ohos { - compileSdkVersion 7 - defaultConfig { - compatibleSdkVersion 7 ->>>>>>> 0e50d605db36ff6e317e21b849a5220bed711ca3 -======= compatibleSdkVersion 7 ->>>>>>> a7fd881db71f93f9ba2923fc2ed13ab77577dd33 } buildTypes { release { @@ -29,29 +13,11 @@ ohos { } } } -<<<<<<< HEAD -<<<<<<< HEAD -======= - supportSystem "standard" ->>>>>>> 0e50d605db36ff6e317e21b849a5220bed711ca3 -======= - supportSystem "standard" ->>>>>>> a7fd881db71f93f9ba2923fc2ed13ab77577dd33 } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) testImplementation 'junit:junit:4.13' -<<<<<<< HEAD -<<<<<<< HEAD - ohosTestImplementation 'com.huawei.ohos.testkit:runner:2.0.0.100' -} -decc { - supportType = ['html','xml'] -======= ->>>>>>> 0e50d605db36ff6e317e21b849a5220bed711ca3 -======= ->>>>>>> a7fd881db71f93f9ba2923fc2ed13ab77577dd33 } diff --git a/Data/JsDistributedData/entry/src/main/config.json b/Data/JsDistributedData/entry/src/main/config.json index 14abcbda0ac2bf4cce10c7c31a14d3145b2e4eea..c21b6a9cd47620f27aaafb7f64f5de060f5f16ba 100644 --- a/Data/JsDistributedData/entry/src/main/config.json +++ b/Data/JsDistributedData/entry/src/main/config.json @@ -1,6 +1,6 @@ { "app": { - "bundleName": "com.ohos.distributed", + "bundleName": "com.huawei.cookbook", "vendor": "huawei", "version": { "code": 1000000, @@ -11,7 +11,7 @@ "module": { "package": "com.huawei.myapplication", "name": ".MyApplication", - "mainAbility": "com.huawei.myapplication.MainAbility", + "mainAbility": ".MainAbility", "deviceType": [ "phone" ], @@ -19,7 +19,7 @@ "deliveryWithInstall": true, "moduleName": "entry", "moduleType": "entry", - "installationFree": false + "installationFree": true }, "abilities": [ { @@ -35,7 +35,9 @@ ], "orientation": "unspecified", "visible": true, - "name": "com.huawei.myapplication.MainAbility", + "srcPath": "MainAbility", + "name": ".MainAbility", + "srcLanguage": "js", "icon": "$media:icon", "description": "$string:mainability_description", "formsEnabled": false, @@ -49,7 +51,7 @@ "pages": [ "pages/index/index" ], - "name": "default", + "name": ".MainAbility", "window": { "designWidth": 720, "autoDesignWidth": false diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/app.js b/Data/JsDistributedData/entry/src/main/js/MainAbility/app.js similarity index 100% rename from Distributed/NewsDemo/entry/src/main/js/MainAbility2/app.js rename to Data/JsDistributedData/entry/src/main/js/MainAbility/app.js diff --git a/Data/JsDistributedData/entry/src/main/js/default/i18n/en-US.json b/Data/JsDistributedData/entry/src/main/js/MainAbility/i18n/en-US.json similarity index 100% rename from Data/JsDistributedData/entry/src/main/js/default/i18n/en-US.json rename to Data/JsDistributedData/entry/src/main/js/MainAbility/i18n/en-US.json diff --git a/Data/JsDistributedData/entry/src/main/js/default/i18n/zh-CN.json b/Data/JsDistributedData/entry/src/main/js/MainAbility/i18n/zh-CN.json similarity index 100% rename from Data/JsDistributedData/entry/src/main/js/default/i18n/zh-CN.json rename to Data/JsDistributedData/entry/src/main/js/MainAbility/i18n/zh-CN.json diff --git a/Data/JsDistributedData/entry/src/main/js/default/pages/index/index.css b/Data/JsDistributedData/entry/src/main/js/MainAbility/pages/index/index.css similarity index 100% rename from Data/JsDistributedData/entry/src/main/js/default/pages/index/index.css rename to Data/JsDistributedData/entry/src/main/js/MainAbility/pages/index/index.css diff --git a/Data/JsDistributedData/entry/src/main/js/default/pages/index/index.hml b/Data/JsDistributedData/entry/src/main/js/MainAbility/pages/index/index.hml similarity index 100% rename from Data/JsDistributedData/entry/src/main/js/default/pages/index/index.hml rename to Data/JsDistributedData/entry/src/main/js/MainAbility/pages/index/index.hml diff --git a/Data/JsDistributedData/entry/src/main/js/default/pages/index/index.js b/Data/JsDistributedData/entry/src/main/js/MainAbility/pages/index/index.js similarity index 96% rename from Data/JsDistributedData/entry/src/main/js/default/pages/index/index.js rename to Data/JsDistributedData/entry/src/main/js/MainAbility/pages/index/index.js index ec8448f321ab3b2c22ef2da42939b5d397b00808..addaaa3ed5f0af48ca400c6880ea65657f3ebeae 100644 --- a/Data/JsDistributedData/entry/src/main/js/default/pages/index/index.js +++ b/Data/JsDistributedData/entry/src/main/js/MainAbility/pages/index/index.js @@ -18,8 +18,8 @@ import KvStoreModel from '../../../model/KvStoreModel.js'; export default { data: { dialogTitle: '', - name: '', - phone: '', + name:'', + phone:'', contactList: [], listIndex: -1, deleteIndex: -1, @@ -31,6 +31,7 @@ export default { // type表示操作0:插入数据、1:修改数据:2:删除数据 this.kvStoreModel.setOnMessageReceivedListener((k, y, type) => { + console.info("type=="+type); if (type === 0) { const obj = { name: y, phone: k @@ -65,8 +66,8 @@ export default { }, // 关闭添加或编辑信息弹窗 cancelDialog() { - this.name = ''; - this.phone = ''; + this.name =''; + this.phone =''; this.$element('addDialog').close(); }, confirmClick() { @@ -77,10 +78,11 @@ export default { const obj = { name: this.name, phone: this.phone }; + this.kvStoreModel.broadcastMessage(this.phone,this.name); this.contactList.push(obj); - this.kvStoreModel.broadcastMessage(this.phone, this.name); } else { this.contactList[this.listIndex].name = this.name; + this.kvStoreModel.broadcastMessage(this.phone, this.name); } this.cancelDialog(); }, @@ -126,7 +128,6 @@ export default { this.phone = obj.phone; this.listIndex = index; this.disableValue = true; - this.kvStoreModel.broadcastMessage(this.phone, this.name); this.showDialog(); }, deleteContact(index) { diff --git a/Data/JsDistributedData/entry/src/main/js/model/KvStoreModel.js b/Data/JsDistributedData/entry/src/main/js/model/KvStoreModel.js index 0f170b443aee22f2fcb0b0725f14bbc39c94876d..0bf98fdcbd39c76dcaef12e530736fae139657cb 100644 --- a/Data/JsDistributedData/entry/src/main/js/model/KvStoreModel.js +++ b/Data/JsDistributedData/entry/src/main/js/model/KvStoreModel.js @@ -42,7 +42,6 @@ export default class KvStoreModel { backup: false, autoSync: true, kvStoreType: 1, - schema: '', securityLevel: 3, }; self.kvManager.getKVStore(STORE_ID, options).then((store) => { @@ -55,10 +54,10 @@ export default class KvStoreModel { } } - broadcastMessage(key, value) { + broadcastMessage(key,value) { let self = this; this.createKvStore(() => { - self.put(key, value); + self.put(key,value+";"); }); } @@ -69,9 +68,12 @@ export default class KvStoreModel { }); } - put(key, value) { - this.kvStore.put(key, value).then((data) => { + put(key,value) { + console.info('dataChange:' + key+"-------"+value+"----------"+value.length); + this.kvStore.put(key,value).then((data) => { + console.info('dataChange:' + JSON.stringify(data)); this.kvStore.get(key).then((data) => { + console.info('dataChange:' + JSON.stringify(data)); }); }).catch((err) => { }); @@ -87,12 +89,17 @@ export default class KvStoreModel { let self = this; this.createKvStore(() => { self.kvStore.on('dataChange', 1, (data) => { + console.info('dataChange:' + JSON.stringify(data)); for (var i = 0; i < data.insertEntries.length; i++) { - callback(data.insertEntries[0].key, data.insertEntries[0].value.value, 0); + var str = data.insertEntries[0].value.value.toString(); + var strs = str.split(';'); + callback(data.insertEntries[0].key,strs[0], 0); return; } for (i = 0; i < data.updateEntries.length; i++) { - callback(data.updateEntries[0].key, data.updateEntries[0].value.value, 1); + var str = data.updateEntries[0].value.value.toString(); + var strs = str.split(';'); + callback(data.updateEntries[0].key,strs[0], 1); return; } for (i = 0; i < data.deleteEntries.length; i++) { diff --git a/Data/JsDistributedData/figures/IMG_20211213_103011.jpg b/Data/JsDistributedData/figures/IMG_20211213_103011.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5c162aaab1e9421bc1b7d2571728a840b85897d Binary files /dev/null and b/Data/JsDistributedData/figures/IMG_20211213_103011.jpg differ diff --git a/Data/JsDistributedData/figures/IMG_20211217_144057.jpg b/Data/JsDistributedData/figures/IMG_20211217_144057.jpg new file mode 100644 index 0000000000000000000000000000000000000000..157e7be6e99ec8de3693331d74adae9b057298e5 Binary files /dev/null and b/Data/JsDistributedData/figures/IMG_20211217_144057.jpg differ diff --git a/Data/JsDistributedData/figures/pin.png b/Data/JsDistributedData/figures/pin.png new file mode 100644 index 0000000000000000000000000000000000000000..06badab0e9ffd8c87cc82e9f448f351a0d6f5bae Binary files /dev/null and b/Data/JsDistributedData/figures/pin.png differ diff --git a/Data/JsDistributedData/figures/zh-cn_image_0000001189809642.gif b/Data/JsDistributedData/figures/zh-cn_image_0000001189809642.gif new file mode 100644 index 0000000000000000000000000000000000000000..1ac28a5f30cce818faa45602edad265c35544138 Binary files /dev/null and b/Data/JsDistributedData/figures/zh-cn_image_0000001189809642.gif differ diff --git a/Data/JsDistributedData/figures/zh-cn_image_0000001237668963.png b/Data/JsDistributedData/figures/zh-cn_image_0000001237668963.png new file mode 100644 index 0000000000000000000000000000000000000000..d04f1b3bead6d596f3d166dca87bece6614bffea Binary files /dev/null and b/Data/JsDistributedData/figures/zh-cn_image_0000001237668963.png differ diff --git "a/Data/JsDistributedData/figures/\344\277\241.png" "b/Data/JsDistributedData/figures/\344\277\241.png" new file mode 100644 index 0000000000000000000000000000000000000000..49074a428c2308a29171362bf46171d80c8927f0 Binary files /dev/null and "b/Data/JsDistributedData/figures/\344\277\241.png" differ diff --git "a/Data/JsDistributedData/figures/\345\217\226\347\211\210\346\234\254.png" "b/Data/JsDistributedData/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/Data/JsDistributedData/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/Data/JsDistributedData/figures/\346\210\252\345\233\276.png" "b/Data/JsDistributedData/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/Data/JsDistributedData/figures/\346\210\252\345\233\276.png" differ diff --git "a/Data/JsDistributedData/figures/\347\241\256\350\256\244.png" "b/Data/JsDistributedData/figures/\347\241\256\350\256\244.png" new file mode 100644 index 0000000000000000000000000000000000000000..4e8a02292e7dfdc20865a8befb3e23ecf0053222 Binary files /dev/null and "b/Data/JsDistributedData/figures/\347\241\256\350\256\244.png" differ diff --git "a/Data/JsDistributedData/figures/\351\237\263\344\271\220.png" "b/Data/JsDistributedData/figures/\351\237\263\344\271\220.png" new file mode 100644 index 0000000000000000000000000000000000000000..a473a3a4a39363f60b6b36cdd930b23aeeab9445 Binary files /dev/null and "b/Data/JsDistributedData/figures/\351\237\263\344\271\220.png" differ diff --git a/Data/JsDistributedData/public_sys-resources/icon-caution.gif b/Data/JsDistributedData/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Data/JsDistributedData/public_sys-resources/icon-caution.gif differ diff --git a/Data/JsDistributedData/public_sys-resources/icon-danger.gif b/Data/JsDistributedData/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Data/JsDistributedData/public_sys-resources/icon-danger.gif differ diff --git a/Data/JsDistributedData/public_sys-resources/icon-note.gif b/Data/JsDistributedData/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/Data/JsDistributedData/public_sys-resources/icon-note.gif differ diff --git a/Data/JsDistributedData/public_sys-resources/icon-notice.gif b/Data/JsDistributedData/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/Data/JsDistributedData/public_sys-resources/icon-notice.gif differ diff --git a/Data/JsDistributedData/public_sys-resources/icon-tip.gif b/Data/JsDistributedData/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/Data/JsDistributedData/public_sys-resources/icon-tip.gif differ diff --git a/Data/JsDistributedData/public_sys-resources/icon-warning.gif b/Data/JsDistributedData/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Data/JsDistributedData/public_sys-resources/icon-warning.gif differ diff --git a/Distributed/DistributeDatabaseDrawEts/LICENSE b/Distributed/DistributeDatabaseDrawEts/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..80576ef141485b36eea4aebf25af97020bc2de44 --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + + 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/Distributed/DistributeDatabaseDrawEts/README.md b/Distributed/DistributeDatabaseDrawEts/README.md index 1586e959ede664d5e6d51c66ca6e914593515558..260f6b05819476ab36c2aab07f6b3538840fabab 100644 --- a/Distributed/DistributeDatabaseDrawEts/README.md +++ b/Distributed/DistributeDatabaseDrawEts/README.md @@ -1,2 +1,845 @@ -tmp +# 1.介绍 +本篇Codelab是用基于TS扩展的声明式开发范式开发一个分布式手写板应用。涉及的OS特性有分布式拉起和分布式数据管理,使用这两个特性实现不同设备间拉起与笔迹同步,即每台设备在书写的时候,连接的其他设备都能实时同步笔迹,效果图如下: + +![](figures/1.gif) + +![](figures/2.gif) + +# 2.相关概念 + +[Path组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-drawing-components-path.md) + +[分布式数据库](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-distributed-data.md) + +[FeatureAbility](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-featureAbility.md) + +# 3.搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 4.分布式组网 + +本章节以系统自带的音乐播放器为例,介绍如何完成两台设备的分布式组网。 + +1. 硬件准备:准备两台烧录相同的版本系统的**Hi3516DV300**开发板A,B。 + +2. 两个开发板A,B配置在同一个WiFi网络之下。 + + 打开设置--\>WLAN--\>点击右侧WiFi开关--\>点击目标WiFi并输入密码。 + + ![](figures/IMG_20211217_144057.jpg) + +3. 将设备A,B设置为互相信任的设备。 + + - 找到系统应用“音乐”。 + + ![](figures/音乐.png) + + - 设备A打开音乐,点击左下角流转按钮,弹出列表框,在列表中会展示远端设备的id。 + + ![](figures/IMG_20211213_103011.jpg) + + - 选择远端设备B的id,另一台开发板(设备B)会弹出验证的选项框。 + + ![](figures/信.png) + + - 设备B点击允许,设备B将会弹出随机PIN码,将设备B的PIN码输入到设备A的PIN码填入框中。 + + ![](figures/pin.png)![](figures/确认.png) + + 配网完毕。 + +# 5.代码结构解读 + +本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在[参考](参考.md)中提供下载方式,整个工程的代码结构如下: + +![](figures/zh-cn_image_0000001192614852.png) + +- common:存放公共资源 + + media:存放图片 + +- model:存放数据模型类 + +- KvStoreModel.ts:分布式数据存储类 + +- RemoteDeviceModel.ts:远程设备类 + +- pages:存放页面 + + index.ets:主页面 + +- config.json:配置文件 + +# 6.编写数据类对象 + +1. 编写分布式数据类对象 + + 我们需要创建RemoteDeviceModel类来完成远程设备管理的初始化,RemoteDeviceModel .ts代码如下: + + ``` + import deviceManager from '@ohos.distributedHardware.deviceManager'; + var SUBSCRIBE_ID = 100; + export default class RemoteDeviceModel { + // 设备列表 + deviceList: any[] = [] + // 回调 + callback: any + // 设备管理Manager + #deviceManager: any + // 构造方法 + constructor() { + } + //注册设备回调方法 + registerDeviceListCallback(callback) { + if (typeof (this.#deviceManager) === 'undefined') { + let self = this; + deviceManager.createDeviceManager('com.ohos.distributedRemoteStartFA', (error, value) => { + if (error) { + console.error('createDeviceManager failed.'); + return; + } + self.#deviceManager = value; + self.registerDeviceListCallback_(callback); + }); + } else { + this.registerDeviceListCallback_(callback); + } + } + //注册设备回调方法 + registerDeviceListCallback_(callback) { + this.callback = callback; + if (this.#deviceManager == undefined) { + this.callback(); + return; + } + + console.info('CookBook[RemoteDeviceModel] getTrustedDeviceListSync begin'); + var list = this.#deviceManager.getTrustedDeviceListSync(); + if (typeof (list) != 'undefined' && typeof (list.length) != 'undefined') { + this.deviceList = list; + } + this.callback(); + let self = this; + this.#deviceManager.on('deviceStateChange', (data) => { + switch (data.action) { + case 0: + self.deviceList[self.deviceList.length] = data.device; + self.callback(); + if (self.authCallback != null) { + self.authCallback(); + self.authCallback = null; + } + break; + case 2: + if (self.deviceList.length > 0) { + for (var i = 0; i < self.deviceList.length; i++) { + if (self.deviceList[i].deviceId === data.device.deviceId) { + self.deviceList[i] = data.device; + break; + } + } + } + self.callback(); + break; + case 1: + if (self.deviceList.length > 0) { + var list = []; + for (var i = 0; i < self.deviceList.length; i++) { + if (self.deviceList[i].deviceId != data.device.deviceId) { + list[i] = data.device; + } + } + self.deviceList = list; + } + self.callback(); + break; + default: + break; + } + }); + this.#deviceManager.on('deviceFound', (data) => { + console.info('CookBook[RemoteDeviceModel] deviceFound data=' + JSON.stringify(data)); + console.info('CookBook[RemoteDeviceModel] deviceFound self.deviceList=' + self.deviceList); + console.info('CookBook[RemoteDeviceModel] deviceFound self.deviceList.length=' + self.deviceList.length); + for (var i = 0; i < self.discoverList.length; i++) { + if (self.discoverList[i].deviceId === data.device.deviceId) { + console.info('CookBook[RemoteDeviceModel] device founded, ignored'); + return; + } + } + self.discoverList[self.discoverList.length] = data.device; + self.callback(); + }); + this.#deviceManager.on('discoverFail', (data) => { + console.info('CookBook[RemoteDeviceModel] discoverFail data=' + JSON.stringify(data)); + }); + this.#deviceManager.on('serviceDie', () => { + console.error('CookBook[RemoteDeviceModel] serviceDie'); + }); + + SUBSCRIBE_ID = Math.floor(65536 * Math.random()); + var info = { + subscribeId: SUBSCRIBE_ID, + mode: 0xAA, + medium: 2, + freq: 2, + isSameAccount: false, + isWakeRemote: true, + capability: 0 + }; + console.info('CookBook[RemoteDeviceModel] startDeviceDiscovery ' + SUBSCRIBE_ID); + this.#deviceManager.startDeviceDiscovery(info); + } + //身份验证 + authDevice(deviceId, callback) { + console.info('CookBook[RemoteDeviceModel] authDevice ' + deviceId); + for (var i = 0; i < this.discoverList.length; i++) { + if (this.discoverList[i].deviceId === deviceId) { + console.info('CookBook[RemoteDeviceModel] device founded, ignored'); + let extraInfo = { + "targetPkgName": 'com.ohos.distributedRemoteStartFA', + "appName": 'demo', + "appDescription": 'demo application', + "business": '0' + }; + let authParam = { + "authType": 1, + "appIcon": '', + "appThumbnail": '', + "extraInfo": extraInfo + }; + console.info('CookBook[RemoteDeviceModel] authenticateDevice ' + JSON.stringify(this.discoverList[i])); + let self = this; + this.#deviceManager.authenticateDevice(this.discoverList[i], authParam, (err, data) => { + if (err) { + console.info('CookBook[RemoteDeviceModel] authenticateDevice failed, err=' + JSON.stringify(err)); + self.authCallback = null; + } else { + console.info('CookBook[RemoteDeviceModel] authenticateDevice succeed, data=' + JSON.stringify(data)); + self.authCallback = callback; + } + }); + } + } + } + //取消注册设备回调方法 + unregisterDeviceListCallback() { + console.info('CookBook[RemoteDeviceModel] stopDeviceDiscovery ' + SUBSCRIBE_ID); + this.#deviceManager.stopDeviceDiscovery(SUBSCRIBE_ID); + this.#deviceManager.off('deviceStateChange'); + this.#deviceManager.off('deviceFound'); + this.#deviceManager.off('discoverFail'); + this.#deviceManager.off('serviceDie'); + this.deviceList = []; + } + } + ``` + +2. 编写远程设备类对象 + + 我们需要创建KvStoreModel类来完成[分布式数据管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-distributed-data.md)的初始化工作。首先调用distributedData.createKVManager接口创建一个KVManager对象实例,用于管理数据库对象。然后调用KVManager.getKVStore接口创建并获取KVStore数据库。最后对外提供put、setDataChangeListener方法用于数据写入和订阅数据更新通知。KvStoreModel.ts代码如下: + + ``` + import distributedData from '@ohos.data.distributeddata'; + const STORE_ID = 'DrawBoard_kvstore'; + + export default class KvStoreModel { + kvManager: any; + kvStore: any; + constructor() { + } + // 创建createKvStore对象实例 + createKvStore(callback: any) { + if (typeof (this.kvStore) === 'undefined') { + var config = { + bundleName: 'com.huawei.cookbook', + userInfo: { + userId: '0', + userType: 0 + } + }; + let self = this; + console.info('DrawBoard[KvStoreModel] createKVManager begin'); + distributedData.createKVManager(config).then((manager) => { + console.info('DrawBoard[KvStoreModel] createKVManager success, kvManager=' + JSON.stringify(manager)); + self.kvManager = manager; + var options = { + createIfMissing: true, + encrypt: false, + backup: false, + autoSync: true, + kvStoreType: 1, + schema: '', + securityLevel: 3, + }; + console.info('DrawBoard[KvStoreModel] kvManager.getKVStore begin'); + self.kvManager.getKVStore(STORE_ID, options).then((store: any) => { + console.info('DrawBoard[KvStoreModel] getKVStore success, kvStore=' + store); + self.kvStore = store; + callback(); + }); + console.info('DrawBoard[KvStoreModel] kvManager.getKVStore end'); + }); + console.info('DrawBoard[KvStoreModel] createKVManager end'); + } else { + callback(); + } + } + // 添加数据 + put(key: any, value: any) { + if (typeof (this.kvStore) === 'undefined') { + return; + } + console.info('DrawBoard[KvStoreModel] kvStore.put ' + key + '=' + value); + this.kvStore.put(key, value).then((data: any) => { + this.kvStore.get(key).then((data:any) => { + console.info('DrawBoard[KvStoreModel] kvStore.get ' + key + '=' + JSON.stringify(data)); + }); + console.info('DrawBoard[KvStoreModel] kvStore.put ' + key + ' finished, data=' + JSON.stringify(data)); + }).catch((err: JSON) => { + console.error('DrawBoard[KvStoreModel] kvStore.put ' + key + ' failed, ' + JSON.stringify(err)); + }); + } + // 获取数据 + get(key: any,callback: any) { + this.createKvStore(() => { + this.kvStore.get(key, function (err: any ,data: any) { + console.log("get success data: " + data); + callback(data); + }); + }) + } + // 监听数据变化 + setDataChangeListener(callback: any) { + let self = this; + this.createKvStore(() => { + self.kvStore.on('dataChange', 1, (data: any) => { + if (data.updateEntries.length > 0) { + callback(data); + } + }); + }); + } + } + ``` + +# 7.页面设计 + +分布式手写板页面主要由全屏Path绘制区、顶部操作栏组成。为了实现弹框选择设备的效果,在最外层添加了自定义弹框组件。Path组件设置为全屏显示,根据手指触摸的屏幕坐标直接通过Path绘制轨迹;顶部操作栏加入撤回图标、设备选择图标;自定义弹框加入标题、设备列表。页面样式请在[参考](参考.md)中查看,页面布局在index.ets中实现。 + +在index.ets中按照如下步骤编写: + +1. 页面整体布局 + + ``` + @Entry + @Component + struct Index { + build() { + Column({ space: 1 }) { + // 用于标题栏布局 + Flex() { + }.backgroundColor(Color.Grey).width('100%').height('10%') + // 用于Path绘制区布局 + Flex() { + }.width('100%').height('90%') + }.height('100%').width('100%') + } + ``` + +2. 标题栏布局 + + ``` + @Entry + @Component + struct Index { + build() { + Column({ space: 1 }) { + Flex() { + Image($r('app.media.goback')).width(70).height(70).position({ x: 30, y: 0 }) + Image($r('app.media.ic_hop')).width(70).height(70) + .align(Alignment.TopEnd) + .flexGrow(1) + .position({ x: 375, y: 0 }) + }.backgroundColor(Color.Grey).width('100%').height('10%') + ... + }.height('100%').width('100%') + } + ``` + +3. Path绘制区布局 + + ``` + @Entry + @Component + struct Index { + build() { + Column({ space: 1 }) { + Flex() { + ... + }.backgroundColor(Color.Grey).width('100%').height('10%') + Flex() { + Path().commands(this.pathCommands).strokeWidth(4).fill('none').stroke(Color.Black) + .width('100%') + .height('100%') + }.width('100%').height('90%') + }.height('100%').width('100%') + } + ``` + +4. 自定义弹框设计并引入到主页面中 + + 1. 自定义弹框设计 + + ``` + @CustomDialog + struct CustomDialogExample { + controller: CustomDialogController + cancel: () => void + confirm: (deviceId, deviceName) => void + startAbility: (deviceId, deviceName, positionList) => void + deviceList:() => void + positionList:() => void + build() { + Column() { + Text('设备列表').width('70%').fontSize(20).margin({ top: 10, bottom: 10 }) + Flex({ justifyContent: FlexAlign.SpaceAround }) { + List({ space: 20, initialIndex: 0 }) { + ForEach(this.deviceList, (item) => { + ListItem() { + Text('' + item.name) + .width('100%').height(100).fontSize(16) + .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF) + .onClick((event: ClickEvent) =>{ + this.controller.close(); + this.startAbility(item.id, item.name, this.positionList) + }) + }.editable(true) + }, item => item.id) + } + .listDirection(Axis.Vertical) // 排列方向 + .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线 + .edgeEffect(EdgeEffect.None) // 滑动到边缘无效果 + .chainAnimation(false) // 联动特效关闭 + .onScrollIndex((firstIndex: number, lastIndex: number) => { + console.info('first' + firstIndex) + console.info('last' + lastIndex) + }) + }.margin({ bottom: 10 }) + } + } + } + ``` + + 2. 引入到主页面 + + ``` + @Entry + @Component + struct Index { + ... + dialogController: CustomDialogController = new CustomDialogController({ + builder: CustomDialogExample({ cancel: this.onCancel, confirm: this.onAccept, deviceList: this.deviceList,positionList: this.positionList,startAbility: this.startAbilityContinuation }), + cancel: this.existApp, + autoCancel: true, + deviceList: this.deviceList, + positionList: this.positionList + }) + onCancel() { + console.info('Callback when the first button is clicked') + } + onAccept() { + console.info('Click when confirm') + } + existApp() { + console.info('Click the callback in the blank area') + } + build() { + ... + } + } + ``` + +5. 为页面设置原始数据 + + 1. 在index.ets文件的顶部设置常量数据 + + ``` + // 默认设备 + var DEVICE_LIST_LOCALHOST = { name: '本机', id: 'localhost' }; + // 用于存放点位信息的key值常量 + const CHANGE_POSITION = 'change_position'; + // path组件Command参数初始化值 + const DEfAULT_PATH_COMMAND = ''; + ``` + + 2. 在Index组件(Component)中设置基本参数 + + ``` + @Entry + @Component + struct Index { + // 触控起始位置X轴坐标 + @State startX: number = 0 + // 触控起始位置Y轴坐标 + @State startY: number = 0 + // 触控移动后的位置X轴坐标 + @State moveX: number = 0 + // 触控移动后的位置Y轴坐标 + @State moveY: number = 0 + // 触控结束后的位置X轴坐标 + @State endX: number = 0 + // 触控结束后的位置Y轴坐标 + @State endY: number = 0 + // Path 组件Command属性值,默认为'' + @State pathCommands: string = DEfAULT_PATH_COMMAND + // 设备列表 + @State deviceList: any[] = [] + // BUNDLE_NAME + private BUNDLE_NAME: string = "com.huawei.cookbook"; + // 分布式数据库类对象 + private kvStoreModel: KvStoreModel = new KvStoreModel() + // 远程设备类对象 + private remoteDeviceModel: RemoteDeviceModel = new RemoteDeviceModel() + // 点位集合 + @State positionList: any[] = [] + // 初始化数据 + @State initialData: any[] = [] + // 是否同步 + private isNeedSync: boolean = false + // 间隔ID + private intervalID: number = 0 + ... + build() { + ... + } + } + ``` + +# 8.设备拉起 + +点击操作栏“分享图标”,弹出设备选择列表,选中设备后拉起该设备的手写板页面。这里使用[分布式拉起](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-featureAbility.md)实现设备拉起功能,首先调用FeatureAbility.getDeviceList接口获取设备信息列表,然后调用FeatureAbility.startAbility接口拉起目标设备的FA。此功能在index.js中实现。 + +![](figures/1-0.gif) + +1. 分享图标添加点击事件 + + ``` + Image($r('app.media.ic_hop')).width(70).height(70) + .align(Alignment.TopEnd) + .flexGrow(1) + .position({ x: 375, y: 0 }) + .onClick((event: ClickEvent) =>{ + this.onContinueAbilityClick() + }) + ``` + +2. 分布式拉起方法实现 + + ``` + onContinueAbilityClick() { + console.info('DrawBoard[IndexPage] onContinueAbilityClick'); + let self = this; + this.remoteDeviceModel.registerDeviceListCallback(() => { + console.info('DrawBoard[IndexPage] registerDeviceListCallback, callback entered'); + var list = []; + list[0] = DEVICE_LIST_LOCALHOST + var deviceList = self.remoteDeviceModel.deviceList; + console.info('DrawBoard[IndexPage] on remote device updated, count=' + deviceList.length); + for (var i = 0; i < deviceList.length; i++) { + console.info('DrawBoard[IndexPage] device ' + i + '/' + deviceList.length + ' deviceId=' + + deviceList[i].deviceId + ' deviceName=' + deviceList[i].deviceName + ' deviceType=' + + deviceList[i].deviceType); + list[i + 1] = { + name: deviceList[i].deviceName, + id: deviceList[i].deviceId, + }; + } + self.deviceList = list; + self.dialogController.open() + }); + } + ``` + +# 9.笔记绘制 + +Path组件所在的Flex容器组件添加点击事件,并实现记录触控点位信息,绘制轨迹的功能。 + +1. 添加点击事件 + + ``` + Flex() { + Path().commands(this.pathCommands).strokeWidth(4).fill('none').stroke(Color.Black) + .width('100%') + .height('100%') + }.onTouch((event: TouchEvent) => { + this.onTouchEvent(event) + }).width('100%').height('90%') + ``` + +2. 现记录触控点位信息的方法 + + ``` + onTouchEvent(event: TouchEvent) { + let position = {}; + switch(event.type){ + // 触控按下 + case TouchType.Down: + this.startX = event.touches[0].x + this.startY = event.touches[0].y + this.pathCommands += ' M' + this.startX + ' ' + this.startY + position.isFirstPosition = true; + position.positionX = this.startX; + position.positionY = this.startY; + this.pushData(position); + break; + // 触控移动 + case TouchType.Move: + this.moveX = event.touches[0].x + this.moveY = event.touches[0].y + this.pathCommands += ' L' + this.moveX + ' ' + this.moveY + position.isFirstPosition = false; + position.positionX = this.moveX; + position.positionY = this.moveY; + this.pushData(position); + break; + // 触控抬起 + case TouchType.Up: + this.endX = event.touches[0].x + this.endY = event.touches[0].y + position.isFirstPosition = false; + position.positionX = this.moveX; + position.positionY = this.moveY; + this.pushData(position); + break; + default: + break + } + } + ``` + +# 10.笔记撤回 + +笔迹绘制时已经记录了所有笔迹上的坐标点,点击“撤回”按钮后,对记录的坐标点进行倒序删除,当删除最后一笔绘制的起始点坐标后停止删除,然后清空画布对剩余的坐标点进行重新绘制,至此撤回操作完成。此功能在index.ets中实现,代码如下: + +1. 添加撤回事件 + + ``` + Image($r('app.media.goback')).width(70).height(70).position({ x: 30, y: 0 }) + .onClick((event: ClickEvent) =>{ + this.goBack() + }) + ``` + +2. 编写撤回事件 + + ``` + // 撤回上一笔绘制 + goBack() { + if (this.positionList.length > 0) { + for (let i = this.positionList.length - 1; i > -1; i--) { + if (this.positionList[i].isFirstPosition) { + this.positionList.pop(); + this.redraw(); + break; + } else { + this.positionList.pop(); + } + } + // 保存点位信息 + this.kvStoreModel.put(CHANGE_POSITION, JSON.stringify(this.positionList)); + } + } + ``` + +# 11.轨迹同步 + +在设备拉起、笔迹绘制、笔迹撤回时我们需要将对应数据同步到其他设备。 + +![](figures/2-1.gif) + +1. 设备拉起时,通过positionList将笔迹数据发送给目标设备,目标设备在aboutToAppear时将接收到的笔迹数据用Path绘制出来,从而实现笔迹的同步。此功能在index.ets中实现,关键代码如下: + + 发送端 + + ``` + startAbilityContinuation(deviceId: string, deviceName: string,positionList: any[] ) { + // 参数 + var params = { + // 点位集合 + positionList: JSON.stringify(positionList) + } + // 拉起的设备、ability信息等 + var wantValue = { + bundleName: 'com.huawei.cookbook', + abilityName: 'com.huawei.distributedatabasedrawetsopenh.MainAbility', + deviceId: deviceId, + parameters: params + }; + // 分布式拉起 + featureAbility.startAbility({ + want: wantValue + }).then((data) => { + console.info('DrawBoard[IndexPage] featureAbility.startAbility finished, ' + JSON.stringify(data)); + }); + } + ``` + + 接收端 + + ``` + // 函数在创建自定义组件的新实例后,在执行其build函数之前执行 + async aboutToAppear() { + console.info('DrawBoard[IndexPage] aboutToAppear begin'); + this.initialData = [] + let self = this + // 获取接收的数据 + await featureAbility.getWant() + .then((Want) => { + self.positionList = JSON.parse(Want.parameters.positionList) + }).catch((error) => { + console.error('Operation failed. Cause: ' + JSON.stringify(error)); + }) + //如果传来的点位集合不为空 + if (this.positionList.length > 0) { + this.positionList.forEach((num) => { + this.initialData.push(num); + }); + // 初始化绘制方法 + this.initDraw(); + } + // 监听分布式数据库中点位信息变化 + this.kvStoreModel.setDataChangeListener((data) => { + self.positionList = []; + data.updateEntries.forEach((num) => { + const list = JSON.parse(num.value.value); + console.info('DrawBoard[IndexPage] setDataChangeListener list=' + JSON.stringify(list)) + if(list.length === 0) { + self.pathCommands = DEfAULT_PATH_COMMAND + } else{ + // 如果不为空,则将数据库中的点位信息添加到页面中 + list.forEach((num) => { + self.positionList.push(num); + }) + } + setTimeout(function() { + // 重绘路径 + self.redraw(); + }, 10); + }); + }); + } + ... + // 初始化画板轨迹 + initDraw() { + const self = this; + self.pathCommands = DEfAULT_PATH_COMMAND + this.intervalID = setInterval(function() { + if (self.initialData[0].isFirstPosition) { + self.pathCommands += ' M' + self.initialData[0].positionX + ' ' + self.initialData[0].positionY + } else { + self.pathCommands += ' L' + self.initialData[0].positionX + ' ' + self.initialData[0].positionY + } + self.initialData.shift(); + if (self.initialData.length < 1) { + clearInterval(self.intervalID); + self.intervalID = 0; + } + }, 10); + } + ``` + +2. 笔迹绘制时,为了避免分布式数据库写入过于频繁,需要使用定时器setInterval,笔迹数据每100ms写入一次。其他设备通过订阅分布式数据更新通知来获取最新的笔迹数据,然后重新绘制笔迹,从而实现笔迹同步。此功能在index.js中实现,关键代码如下: + + 发送端 + + ``` + // 将绘制笔迹写入分布式数据库 + pushData(position) { + this.isNeedSync = true; + this.positionList.push(position); + const self = this; + + // 使用定时器每100ms写入一次 + if (this.intervalID === 0) { + this.intervalID = setInterval(function() { + if (self.isNeedSync) { + self.kvStoreModel.put(CHANGE_POSITION, JSON.stringify(self.positionList)); + self.isNeedSync = false; + } + }, DATA_PUT_DELAY); + } + }, + ``` + + 接收端 + + ``` + onInit() { + ... + // 订阅分布式数据更新通知 + this.kvStoreModel.setDataChangeListener((data) => { + data.updateEntries.forEach((num) => { + this.positionList = []; + const list = JSON.parse(num.value.value); + list.forEach((num) => { + this.positionList.push(num); + }) + const self = this; + setTimeout(function() { + self.redraw(); + }, DRAW_DELAY); + }); + }); + }, + // 重新绘制笔迹 + redraw() { + // 清空画布 + this.ctx.clearRect(0, 0, CLEAR_WIDTH, CLEAR_HEIGHT); + this.positionList.forEach((num) => { + if (num.isStartPosition) { + this.ctx.beginPath(); + this.ctx.moveTo(num.positionX, num.positionY); + } else { + this.ctx.lineTo(num.positionX, num.positionY); + this.ctx.stroke(); + } + }); + }, + ``` + +3. 笔迹撤回时,直接将撤回后的笔迹数据写入分布式数据库,其他设备也是通过订阅分布式数据更新通知来获取最新的笔迹数据,最终实现笔迹同步,这里不再做讲解。 + +# 12.恭喜你 + +通过本教程的学习,您已经学会使用基于TS扩展的声明式开发范式中的分布式数据管理和分布式拉起以及利用Path组件绘制图形。 + +# 13.参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/Distributed/DistributeDatabaseDrawEts) \ No newline at end of file diff --git a/Distributed/DistributeDatabaseDrawEts/build.gradle b/Distributed/DistributeDatabaseDrawEts/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..8091e0ece10575993ba570722aadd6788144f460 --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/build.gradle @@ -0,0 +1,34 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + supportSystem "standard" +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } + dependencies { + classpath 'com.huawei.ohos:hap:3.0.3.4' + classpath 'com.huawei.ohos:decctest:1.2.6.0' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } +} diff --git a/Distributed/DistributeDatabaseDrawEts/entry/.gitignore b/Distributed/DistributeDatabaseDrawEts/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7d5b7a94f4dcf381f03ff21f28f8a2494b58023f --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/entry/.gitignore @@ -0,0 +1,2 @@ +/build +/node_modules diff --git a/Distributed/DistributeDatabaseDrawEts/entry/build.gradle b/Distributed/DistributeDatabaseDrawEts/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..4879de33706b7f666cfdcfbc46a8e95cefa9f429 --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/entry/build.gradle @@ -0,0 +1,32 @@ +apply plugin: 'com.huawei.ohos.hap' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + signingConfigs { + debug { + storeFile file('D:\\openHos\\openhos.p12') + storePassword '00000018EAE05FDE239C72555D7E3A75AAAE8D5C8473E899062886CC5B1C5806824D76E04A3FDCFE' + keyAlias = 'hw' + keyPassword '000000188A095D85008CC89636DE77E8A1622CF14921FF9894B254F7CD41BBF6A0C1E51A641EA3B6' + signAlg = 'SHA256withECDSA' + profile file('D:\\openHos\\openHos.p7b') + certpath file('D:\\openHos\\openHos.cer') + } + } + compileSdkVersion 7 + defaultConfig { + compatibleSdkVersion 7 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13.1' +} diff --git a/Distributed/DistributeDatabaseDrawEts/entry/proguard-rules.pro b/Distributed/DistributeDatabaseDrawEts/entry/proguard-rules.pro new file mode 100644 index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/entry/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/Distributed/DistributeDatabaseDrawEts/entry/src/main/config.json b/Distributed/DistributeDatabaseDrawEts/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..652eb7a49349e538384bfc2898edbe522b427b92 --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/entry/src/main/config.json @@ -0,0 +1,66 @@ +{ + "app": { + "bundleName": "com.huawei.cookbook", + "vendor": "huawei", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "com.huawei.distributedatabasedrawetsopenh", + "name": ".MyApplication", + "mainAbility": ".MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "visible": true, + "srcPath": "MainAbility", + "name": ".MainAbility", + "srcLanguage": "ets", + "icon": "$media:icon", + "description": "$string:description_mainability", + "formsEnabled": false, + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "mode": { + "syntax": "ets", + "type": "pageAbility" + }, + "pages": [ + "pages/index" + ], + "name": ".MainAbility", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} \ No newline at end of file diff --git a/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/app.ets b/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..b7a0995c8e441cac86e21e06e7c9071664482b1c --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/app.ets @@ -0,0 +1,8 @@ +export default { + onCreate() { + console.info('Application onCreate') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} \ No newline at end of file diff --git a/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/common/media/ic_hop.svg b/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/common/media/ic_hop.svg new file mode 100644 index 0000000000000000000000000000000000000000..a3c9baade44146810d8b91691934ab4b7bf98adf --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/common/media/ic_hop.svg @@ -0,0 +1,8 @@ + + + icon_hop + + + + + \ No newline at end of file diff --git a/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/model/KvStoreModel.ts b/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/model/KvStoreModel.ts new file mode 100644 index 0000000000000000000000000000000000000000..af8dd409a2fe026fc1f24faaea6b688b315adf8b --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/model/KvStoreModel.ts @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2021 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 distributedData from '@ohos.data.distributeddata'; + +const STORE_ID = 'DrawBoard_kvstore'; + +export default class KvStoreModel { + kvManager: any; + kvStore: any; + + constructor() { + } + + createKvStore(callback: any) { + if (typeof (this.kvStore) === 'undefined') { + var config = { + bundleName: 'com.huawei.cookbook', + userInfo: { + userId: '0', + userType: 0 + } + }; + let self = this; + console.info('DrawBoard[KvStoreModel] createKVManager begin'); + distributedData.createKVManager(config).then((manager) => { + console.info('DrawBoard[KvStoreModel] createKVManager success, kvManager=' + JSON.stringify(manager)); + self.kvManager = manager; + var options = { + createIfMissing: true, + encrypt: false, + backup: false, + autoSync: true, + kvStoreType: 1, + schema: '', + securityLevel: 3, + }; + console.info('DrawBoard[KvStoreModel] kvManager.getKVStore begin'); + self.kvManager.getKVStore(STORE_ID, options).then((store: any) => { + console.info('DrawBoard[KvStoreModel] getKVStore success, kvStore=' + store); + self.kvStore = store; + callback(); + }); + console.info('DrawBoard[KvStoreModel] kvManager.getKVStore end'); + }); + console.info('DrawBoard[KvStoreModel] createKVManager end'); + } else { + callback(); + } + } + + broadcastMessage(msg: any) { + console.info('DrawBoard[KvStoreModel] broadcastMessage ' + msg); + var num = Math.random(); + let self = this; + this.createKvStore(() => { + self.put(msg, num); + }); + } + + put(key: any, value: any) { + if (typeof (this.kvStore) === 'undefined') { + return; + } + console.info('DrawBoard[KvStoreModel] kvStore.put ' + key + '=' + value); + this.kvStore.put(key, value).then((data: any) => { + this.kvStore.get(key).then((data:any) => { + console.info('DrawBoard[KvStoreModel] kvStore.get ' + key + '=' + JSON.stringify(data)); + }); + console.info('DrawBoard[KvStoreModel] kvStore.put ' + key + ' finished, data=' + JSON.stringify(data)); + }).catch((err: JSON) => { + console.error('DrawBoard[KvStoreModel] kvStore.put ' + key + ' failed, ' + JSON.stringify(err)); + }); + } + + get(key: any,callback: any) { + this.createKvStore(() => { + this.kvStore.get(key, function (err: any ,data: any) { + console.log("get success data: " + data); + callback(data); + }); + }) + } + + setOnMessageReceivedListener(callback: any) { + console.info('DrawBoard[KvStoreModel] setOnMessageReceivedListener '); + let self = this; + this.createKvStore(() => { + console.info('DrawBoard[KvStoreModel] kvStore.on(dataChange) begin'); + self.kvStore.on('dataChange', 1, (data: any) => { + console.info('DrawBoard[KvStoreModel] dataChange, ' + JSON.stringify(data)); + console.info('DrawBoard[KvStoreModel] dataChange, insert ' + data.insertEntries.length + ' udpate ' + + data.updateEntries.length); + if (data.insertEntries.length < 1 && data.updateEntries.length < 1) { + return; + } + + callback(data); + }); + console.info('DrawBoard[KvStoreModel] kvStore.on(dataChange) end'); + }); + } + setDataChangeListener(callback: any) { + let self = this; + this.createKvStore(() => { + self.kvStore.on('dataChange', 1, (data: any) => { + if (data.updateEntries.length > 0) { + callback(data); + } + }); + }); + } +} \ No newline at end of file diff --git a/Distributed/NewsDemo/entry/src/main/js/model/RemoteDeviceModel.js b/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/model/RemoteDeviceModel.ts similarity index 34% rename from Distributed/NewsDemo/entry/src/main/js/model/RemoteDeviceModel.js rename to Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/model/RemoteDeviceModel.ts index 6e91a1a1e68e38ca7b909546aae92b3c78361b37..b5f7beb9d30f084f89b57eab3b0a0b83c4e66c7f 100644 --- a/Distributed/NewsDemo/entry/src/main/js/model/RemoteDeviceModel.js +++ b/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/model/RemoteDeviceModel.ts @@ -18,112 +18,110 @@ import deviceManager from '@ohos.distributedHardware.deviceManager'; var SUBSCRIBE_ID = 100; export default class RemoteDeviceModel { - deviceList = []; - discoverList = []; - callback; - authCallback = null; - #deviceManager; + deviceList: any[] = [] + callback: any + #deviceManager: any constructor() { } - registerDeviceListCallback(callback) { + registerDeviceListCallback(callback: any) { if (typeof (this.#deviceManager) === 'undefined') { - console.log('MusicPlayer[RemoteDeviceModel] deviceManager.createDeviceManager begin'); + console.log('DrawBoard[RemoteDeviceModel] deviceManager.createDeviceManager begin'); let self = this; - deviceManager.createDeviceManager('com.ohos.distributedmusicplayer', (error, value) => { + deviceManager.createDeviceManager('com.ohos.distributedDrawBoard', (error, value) => { if (error) { console.error('createDeviceManager failed.'); return; } self.#deviceManager = value; self.registerDeviceListCallback_(callback); - console.log('MusicPlayer[RemoteDeviceModel] createDeviceManager callback returned, error=' + error + ' value=' + value); + console.log('DrawBoard[RemoteDeviceModel] createDeviceManager callback returned, error=' + error + ' value=' + value); }); - console.log('MusicPlayer[RemoteDeviceModel] deviceManager.createDeviceManager end'); + console.log('DrawBoard[RemoteDeviceModel] deviceManager.createDeviceManager end'); } else { this.registerDeviceListCallback_(callback); } } - registerDeviceListCallback_(callback) { - console.info('MusicPlayer[RemoteDeviceModel] registerDeviceListCallback'); + registerDeviceListCallback_(callback: any) { + console.info('DrawBoard[RemoteDeviceModel] registerDeviceListCallback'); this.callback = callback; if (this.#deviceManager == undefined) { - console.error('MusicPlayer[RemoteDeviceModel] deviceManager has not initialized'); + console.error('DrawBoard[RemoteDeviceModel] deviceManager has not initialized'); this.callback(); return; } - console.info('MusicPlayer[RemoteDeviceModel] getTrustedDeviceListSync begin'); + console.info('DrawBoard[RemoteDeviceModel] getTrustedDeviceListSync begin'); var list = this.#deviceManager.getTrustedDeviceListSync(); - console.info('MusicPlayer[RemoteDeviceModel] getTrustedDeviceListSync end, deviceList=' + JSON.stringify(list)); + console.info('DrawBoard[RemoteDeviceModel] getTrustedDeviceListSync end, deviceList=' + JSON.stringify(list)); if (typeof (list) != 'undefined' && typeof (list.length) != 'undefined') { this.deviceList = list; } this.callback(); - console.info('MusicPlayer[RemoteDeviceModel] callback finished'); + console.info('DrawBoard[RemoteDeviceModel] callback finished'); let self = this; - this.#deviceManager.on('deviceStateChange', (data) => { - console.info('MusicPlayer[RemoteDeviceModel] deviceStateChange data=' + JSON.stringify(data)); + this.#deviceManager.on('deviceStateChange', (data: any) => { + console.info('DrawBoard[RemoteDeviceModel] deviceStateChange data=' + JSON.stringify(data)); switch (data.action) { case 0: - self.deviceList[self.deviceList.length] = data.device; - console.info('MusicPlayer[RemoteDeviceModel] online, updated device list=' + JSON.stringify(self.deviceList)); - self.callback(); - if (self.authCallback != null) { - self.authCallback(); - self.authCallback = null; - } - break; + self.deviceList[self.deviceList.length] = data.device; + console.info('DrawBoard[RemoteDeviceModel] online, updated device list=' + JSON.stringify(self.deviceList)); + self.callback(); + break; case 2: - if (self.deviceList.length > 0) { - for (var i = 0; i < self.deviceList.length; i++) { - if (self.deviceList[i].deviceId === data.device.deviceId) { - self.deviceList[i] = data.device; - break; + if (self.deviceList.length > 0) { + for (var i = 0; i < self.deviceList.length; i++) { + if (self.deviceList[i].deviceId === data.device.deviceId) { + self.deviceList[i] = data.device; + break; + } } } - } - console.info('MusicPlayer[RemoteDeviceModel] change, updated device list=' + JSON.stringify(self.deviceList)); - self.callback(); - break; + console.info('DrawBoard[RemoteDeviceModel] change, updated device list=' + JSON.stringify(self.deviceList)); + self.callback(); + break; case 1: - if (self.deviceList.length > 0) { - var list = []; - for (var i = 0; i < self.deviceList.length; i++) { - if (self.deviceList[i].deviceId != data.device.deviceId) { - list[i] = data.device; + if (self.deviceList.length > 0) { + var list = []; + for (var i = 0; i < self.deviceList.length; i++) { + if (self.deviceList[i].deviceId != data.device.deviceId) { + list[i] = data.device; + } } + self.deviceList = list; } - self.deviceList = list; - } - console.info('MusicPlayer[RemoteDeviceModel] offline, updated device list=' + JSON.stringify(data.device)); - self.callback(); - break; + console.info('DrawBoard[RemoteDeviceModel] offline, updated device list=' + JSON.stringify(data.device)); + self.callback(); + break; default: break; } }); - this.#deviceManager.on('deviceFound', (data) => { - console.info('MusicPlayer[RemoteDeviceModel] deviceFound data=' + JSON.stringify(data)); - console.info('MusicPlayer[RemoteDeviceModel] deviceFound self.deviceList=' + self.deviceList); - console.info('MusicPlayer[RemoteDeviceModel] deviceFound self.deviceList.length=' + self.deviceList.length); - for (var i = 0; i < self.discoverList.length; i++) { - if (self.discoverList[i].deviceId === data.device.deviceId) { - console.info('MusicPlayer[RemoteDeviceModel] device founded, ignored'); + this.#deviceManager.on('deviceFound', (data: any) => { + console.info('DrawBoard[RemoteDeviceModel] deviceFound data=' + JSON.stringify(data)); + console.info('DrawBoard[RemoteDeviceModel] deviceFound self.deviceList=' + self.deviceList); + console.info('DrawBoard[RemoteDeviceModel] deviceFound self.deviceList.length=' + self.deviceList.length); + for (var i = 0; i < self.deviceList.length; i++) { + if (self.deviceList[i].deviceId === data.device.deviceId) { + console.info('DrawBoard[RemoteDeviceModel] device founded, ignored'); return; } } - self.discoverList[self.discoverList.length] = data.device; - self.callback(); + + console.info('DrawBoard[RemoteDeviceModel] authenticateDevice ' + JSON.stringify(data.device)); + self.#deviceManager.authenticateDevice(data.device); }); - this.#deviceManager.on('discoverFail', (data) => { - console.info('MusicPlayer[RemoteDeviceModel] discoverFail data=' + JSON.stringify(data)); + this.#deviceManager.on('discoverFail', (data: any) => { + console.info('DrawBoard[RemoteDeviceModel] discoverFail data=' + JSON.stringify(data)); + }); + this.#deviceManager.on('authResult', (data: any) => { + console.info('DrawBoard[RemoteDeviceModel] authResult data=' + JSON.stringify(data)); }); this.#deviceManager.on('serviceDie', () => { - console.error('MusicPlayer[RemoteDeviceModel] serviceDie'); + console.error('DrawBoard[RemoteDeviceModel] serviceDie'); }); SUBSCRIBE_ID = Math.floor(65536 * Math.random()); @@ -136,48 +134,17 @@ export default class RemoteDeviceModel { isWakeRemote: true, capability: 0 }; - console.info('MusicPlayer[RemoteDeviceModel] startDeviceDiscovery ' + SUBSCRIBE_ID); + console.info('DrawBoard[RemoteDeviceModel] startDeviceDiscovery ' + SUBSCRIBE_ID); this.#deviceManager.startDeviceDiscovery(info); } - authDevice(deviceId, callback) { - console.info('MusicPlayer[RemoteDeviceModel] authDevice ' + deviceId); - for (var i = 0; i < this.discoverList.length; i++) { - if (this.discoverList[i].deviceId === deviceId) { - console.info('MusicPlayer[RemoteDeviceModel] device founded, ignored'); - let extraInfo = { - "targetPkgName": 'com.ohos.distributedmusicplayer', - "appName": 'Music', - "appDescription": 'Music player application', - "business": '0' - }; - let authParam = { - "authType": 1, - "appIcon": '', - "appThumbnail": '', - "extraInfo": extraInfo - }; - console.info('MusicPlayer[RemoteDeviceModel] authenticateDevice ' + JSON.stringify(this.discoverList[i])); - let self = this; - this.#deviceManager.authenticateDevice(this.discoverList[i], authParam, (err, data) => { - if (err) { - console.info('MusicPlayer[RemoteDeviceModel] authenticateDevice failed, err=' + JSON.stringify(err)); - self.authCallback = null; - } else { - console.info('MusicPlayer[RemoteDeviceModel] authenticateDevice succeed, data=' + JSON.stringify(data)); - self.authCallback = callback; - } - }); - } - } - } - unregisterDeviceListCallback() { - console.info('MusicPlayer[RemoteDeviceModel] stopDeviceDiscovery ' + SUBSCRIBE_ID); + console.info('DrawBoard[RemoteDeviceModel] stopDeviceDiscovery ' + SUBSCRIBE_ID); this.#deviceManager.stopDeviceDiscovery(SUBSCRIBE_ID); this.#deviceManager.off('deviceStateChange'); this.#deviceManager.off('deviceFound'); this.#deviceManager.off('discoverFail'); + this.#deviceManager.off('authResult'); this.#deviceManager.off('serviceDie'); this.deviceList = []; } diff --git a/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/pages/index.ets b/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/pages/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..78035ea3a54cf09b96bade5f620bbe0b5e36682c --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/entry/src/main/ets/MainAbility/pages/index.ets @@ -0,0 +1,307 @@ +// @ts-nocheck +import featureAbility from '@ohos.ability.featureAbility'; +import KvStoreModel from '../model/KvStoreModel'; +import RemoteDeviceModel from '../model/RemoteDeviceModel'; +var DEVICE_LIST_LOCALHOST = { name: '本机', id: 'localhost' }; +const CHANGE_POSITION = 'change_position'; +const DEfAULT_PATH_COMMAND = ''; + +@CustomDialog +struct CustomDialogExample { + controller: CustomDialogController + cancel: () => void + confirm: (deviceId, deviceName) => void + startAbility: (deviceId, deviceName, positionList) => void + deviceList:() => void + positionList:() => void +// private selectedDevices: any[]= []; + build() { + Column() { + Text('设备列表').width('70%').fontSize(20).margin({ top: 10, bottom: 10 }) + Flex({ justifyContent: FlexAlign.SpaceAround }) { + List({ space: 20, initialIndex: 0 }) { + ForEach(this.deviceList, (item) => { + ListItem() { + Text('' + item.name) + .width('100%').height(100).fontSize(16) + .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF) + .onClick((event: ClickEvent) =>{ + this.controller.close(); + this.startAbility(item.id, item.name, this.positionList) +// this.confirm(item.id,item.name) + }) + }.editable(true) + }, item => item.id) + } + .listDirection(Axis.Vertical) // 排列方向 + .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线 + .edgeEffect(EdgeEffect.None) // 滑动到边缘无效果 + .chainAnimation(false) // 联动特效关闭 + .onScrollIndex((firstIndex: number, lastIndex: number) => { + console.info('first' + firstIndex) + console.info('last' + lastIndex) + }) + }.margin({ bottom: 10 }) + } + } +} + + +@Entry +@Component +struct Index { + @State startX: number = 0 + @State startY: number = 0 + @State moveX: number = 0 + @State moveY: number = 0 + @State endX: number = 0 + @State endY: number = 0 + @State pathCommands: string = DEfAULT_PATH_COMMAND + @State deviceList: any[] = [] + private BUNDLE_NAME: string = "com.huawei.cookbook"; + private kvStoreModel: KvStoreModel = new KvStoreModel() + private remoteDeviceModel: RemoteDeviceModel = new RemoteDeviceModel() + @State positionList: any[] = [] + @State initialData: any[] = [] + private isNeedSync: boolean = false + private intervalID: number = 0 + + dialogController: CustomDialogController = new CustomDialogController({ + builder: CustomDialogExample({ cancel: this.onCancel, confirm: this.onAccept, deviceList: this.deviceList,positionList: this.positionList,startAbility: this.startAbilityContinuation }), + cancel: this.existApp, + autoCancel: true, + deviceList: this.deviceList, + positionList: this.positionList + }) + onCancel() { + console.info('Callback when the first button is clicked') + } + onAccept() { + console.info('Click when confirm') + } + existApp() { + console.info('Click the callback in the blank area') + } + + build() { + Column({ space: 1 }) { + Flex() { + Image($r('app.media.goback')).width(70).height(70).position({ x: 30, y: 0 }) + .onClick((event: ClickEvent) =>{ + this.goBack() + }) + Image($r('app.media.ic_hop')).width(70).height(70) + .align(Alignment.TopEnd) + .flexGrow(1) + .position({ x: 375, y: 0 }) + .onClick((event: ClickEvent) =>{ + this.onContinueAbilityClick() + }) + }.backgroundColor(Color.Grey).width('100%').height('10%') + Flex() { + Path().commands(this.pathCommands).strokeWidth(4).fill('none').stroke(Color.Black) + .width('100%') + .height('100%') + }.onTouch((event: TouchEvent) => { + this.onTouchEvent(event) + }).width('100%').height('90%') + }.height('100%').width('100%') + } +// 函数在创建自定义组件的新实例后,在执行其build函数之前执行 + async aboutToAppear() { + console.info('DrawBoard[IndexPage] aboutToAppear begin'); + this.initialData = [] + let self = this + await featureAbility.getWant() + .then((Want) => { + self.positionList = JSON.parse(Want.parameters.positionList) + console.info('Operation successful. self.positionList: ' + JSON.stringify(self.positionList.length)); + }).catch((error) => { + console.error('Operation failed. Cause: ' + JSON.stringify(error)); + }) + /*await this.kvStoreModel.get(CHANGE_POSITION,(data)=>{ + console.info('DrawBoard[IndexPage] aboutToAppear data ='+data) + self.positionList = JSON.parse(data) + })*/ + console.info('DrawBoard[IndexPage] aboutToAppear positionList length=' + this.positionList.length); + + if (this.positionList.length > 0) { + this.positionList.forEach((num) => { + this.initialData.push(num); + }); + this.initDraw(); + } + + this.kvStoreModel.setDataChangeListener((data) => { + self.positionList = []; + data.updateEntries.forEach((num) => { + const list = JSON.parse(num.value.value); + console.info('DrawBoard[IndexPage] setDataChangeListener list=' + JSON.stringify(list)) + if(list.length === 0) { + console.info('DrawBoard[IndexPage] setDataChangeListener list.length === 0') + self.pathCommands = DEfAULT_PATH_COMMAND + } else{ + list.forEach((num) => { + self.positionList.push(num); + }) + console.info('DrawBoard[IndexPage] setDataChangeListener positionList=' + JSON.stringify(this.positionList)) + } + setTimeout(function() { + self.redraw(); + }, 10); + }); + }); + } + + // 初始化画板轨迹 + initDraw() { + const self = this; + self.pathCommands = '' + this.intervalID = setInterval(function() { + if (self.initialData[0].isFirstPosition) { + self.pathCommands += ' M' + self.initialData[0].positionX + ' ' + self.initialData[0].positionY + console.info('DrawBoard[IndexPage] initDraw pathCommands=' + self.pathCommands) + + } else { + self.pathCommands += ' L' + self.initialData[0].positionX + ' ' + self.initialData[0].positionY + console.info('DrawBoard[IndexPage] initDraw pathCommands=' + self.pathCommands) + } + self.initialData.shift(); + + if (self.initialData.length < 1) { + clearInterval(self.intervalID); + self.intervalID = 0; + } + }, 10); + } + // 轨迹重绘制 + redraw() { + console.info('DrawBoard[IndexPage] redraw positionList= ' + JSON.stringify(this.positionList)) + this.pathCommands = DEfAULT_PATH_COMMAND + if (this.positionList.length > 0 ) { + this.positionList.forEach((num) => { + console.info('DrawBoard[IndexPage] redraw num=' + JSON.stringify(num)) + if (num.isFirstPosition) { + this.pathCommands += ' M' + num.positionX + ' ' + num.positionY + console.info('DrawBoard[IndexPage] redraw pathCommands=' + this.pathCommands) + } else { + this.pathCommands += ' L' + num.positionX + ' ' + num.positionY + console.info('DrawBoard[IndexPage] redraw pathCommands=' + this.pathCommands) + } + }); + } + } + + // 撤回上一笔绘制 + goBack() { + if (this.positionList.length > 0) { + for (let i = this.positionList.length - 1; i > -1; i--) { + if (this.positionList[i].isFirstPosition) { + this.positionList.pop(); + this.redraw(); + break; + } else { + this.positionList.pop(); + } + } + this.kvStoreModel.put(CHANGE_POSITION, JSON.stringify(this.positionList)); + } + } + + onContinueAbilityClick() { + console.info('DrawBoard[IndexPage] onContinueAbilityClick'); + let self = this; + this.remoteDeviceModel.registerDeviceListCallback(() => { + console.info('DrawBoard[IndexPage] registerDeviceListCallback, callback entered'); + var list = []; + list[0] = DEVICE_LIST_LOCALHOST + var deviceList = self.remoteDeviceModel.deviceList; + console.info('DrawBoard[IndexPage] on remote device updated, count=' + deviceList.length); + for (var i = 0; i < deviceList.length; i++) { + console.info('DrawBoard[IndexPage] device ' + i + '/' + deviceList.length + ' deviceId=' + + deviceList[i].deviceId + ' deviceName=' + deviceList[i].deviceName + ' deviceType=' + + deviceList[i].deviceType); + list[i + 1] = { + name: deviceList[i].deviceName, + id: deviceList[i].deviceId, + }; + } + self.deviceList = list; + self.dialogController.open() + }); + } + + startAbilityContinuation(deviceId: string, deviceName: string,positionList: any[] ) { + var params = { + positionList: JSON.stringify(positionList) + } + console.info('DrawBoard[IndexPage] featureAbility.startAbility positionList=' + JSON.stringify(positionList)) + console.info('DrawBoard[IndexPage] featureAbility.startAbility deviceId=' + deviceId + + ' deviceName=' + deviceName); + var wantValue = { + bundleName: 'com.huawei.cookbook', + abilityName: 'com.huawei.distributedatabasedrawetsopenh.MainAbility', + deviceId: deviceId, + parameters: params + }; + + featureAbility.startAbility({ + want: wantValue + }).then((data) => { + console.info('DrawBoard[IndexPage] featureAbility.startAbility finished, ' + JSON.stringify(data)); + }); + console.info('DrawBoard[IndexPage] featureAbility.startAbility want=' + JSON.stringify(wantValue)); + console.info('DrawBoard[IndexPage] featureAbility.startAbility end'); + } + + + onTouchEvent(event: TouchEvent) { + let position = {}; + switch(event.type){ + case TouchType.Down: + this.startX = event.touches[0].x + this.startY = event.touches[0].y + this.pathCommands += ' M' + this.startX + ' ' + this.startY + position.isFirstPosition = true; + position.positionX = this.startX; + position.positionY = this.startY; + this.pushData(position); + break; + case TouchType.Move: + this.moveX = event.touches[0].x + this.moveY = event.touches[0].y + this.pathCommands += ' L' + this.moveX + ' ' + this.moveY + position.isFirstPosition = false; + position.positionX = this.moveX; + position.positionY = this.moveY; + this.pushData(position); + break; + case TouchType.Up: + this.endX = event.touches[0].x + this.endY = event.touches[0].y + position.isFirstPosition = false; + position.positionX = this.moveX; + position.positionY = this.moveY; + this.pushData(position); + break; + default: + break + } + } + pushData(position: any) { + this.isNeedSync = true; + this.positionList.push(position); + console.info('DrawBoard[IndexPage] pushData positionList 1 =' + JSON.stringify(this.positionList.length)); + let self = this; + if (this.intervalID === 0) { + this.intervalID = setInterval(function () { + if (self.isNeedSync) { + self.kvStoreModel.put(CHANGE_POSITION, JSON.stringify(self.positionList)); + console.info('DrawBoard[IndexPage] pushData positionList 2 =' + JSON.stringify(this.positionList.length)); + // self.positionList = []; + self.isNeedSync = false; + } + }, 100); + } + } +} \ No newline at end of file diff --git a/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/element/string.json b/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..c2b942aa7bd1269253e383b5da168ab147d765f5 --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/element/string.json @@ -0,0 +1,12 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "分布式手写板ETS" + }, + { + "name": "description_mainability", + "value": "ETS_Empty Ability" + } + ] +} \ No newline at end of file diff --git a/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/media/goback.png b/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/media/goback.png new file mode 100644 index 0000000000000000000000000000000000000000..276b223df989c6cc6d6bbb8481fb9d35dc99fa82 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/media/goback.png differ diff --git a/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/media/ic_hop.svg b/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/media/ic_hop.svg new file mode 100644 index 0000000000000000000000000000000000000000..a3c9baade44146810d8b91691934ab4b7bf98adf --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/media/ic_hop.svg @@ -0,0 +1,8 @@ + + + icon_hop + + + + + \ No newline at end of file diff --git a/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/media/icon.png b/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/entry/src/main/resources/base/media/icon.png differ diff --git a/Distributed/DistributeDatabaseDrawEts/figures/1-0.gif b/Distributed/DistributeDatabaseDrawEts/figures/1-0.gif new file mode 100644 index 0000000000000000000000000000000000000000..48827a27bb63fdea1ef0638aa0cf2162992a8120 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/figures/1-0.gif differ diff --git a/Distributed/DistributeDatabaseDrawEts/figures/1.gif b/Distributed/DistributeDatabaseDrawEts/figures/1.gif new file mode 100644 index 0000000000000000000000000000000000000000..48827a27bb63fdea1ef0638aa0cf2162992a8120 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/figures/1.gif differ diff --git a/Distributed/DistributeDatabaseDrawEts/figures/2-1.gif b/Distributed/DistributeDatabaseDrawEts/figures/2-1.gif new file mode 100644 index 0000000000000000000000000000000000000000..380b6e53d5b5239243b42c3aba5b51d29a157840 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/figures/2-1.gif differ diff --git a/Distributed/DistributeDatabaseDrawEts/figures/2.gif b/Distributed/DistributeDatabaseDrawEts/figures/2.gif new file mode 100644 index 0000000000000000000000000000000000000000..380b6e53d5b5239243b42c3aba5b51d29a157840 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/figures/2.gif differ diff --git a/Distributed/DistributeDatabaseDrawEts/figures/IMG_20211213_103011.jpg b/Distributed/DistributeDatabaseDrawEts/figures/IMG_20211213_103011.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5c162aaab1e9421bc1b7d2571728a840b85897d Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/figures/IMG_20211213_103011.jpg differ diff --git a/Distributed/DistributeDatabaseDrawEts/figures/IMG_20211217_144057.jpg b/Distributed/DistributeDatabaseDrawEts/figures/IMG_20211217_144057.jpg new file mode 100644 index 0000000000000000000000000000000000000000..157e7be6e99ec8de3693331d74adae9b057298e5 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/figures/IMG_20211217_144057.jpg differ diff --git a/Distributed/DistributeDatabaseDrawEts/figures/pin.png b/Distributed/DistributeDatabaseDrawEts/figures/pin.png new file mode 100644 index 0000000000000000000000000000000000000000..06badab0e9ffd8c87cc82e9f448f351a0d6f5bae Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/figures/pin.png differ diff --git a/Distributed/DistributeDatabaseDrawEts/figures/zh-cn_image_0000001192614852.png b/Distributed/DistributeDatabaseDrawEts/figures/zh-cn_image_0000001192614852.png new file mode 100644 index 0000000000000000000000000000000000000000..fbfc88b5e8e9e3beb192317f9a6a6be989e2d408 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/figures/zh-cn_image_0000001192614852.png differ diff --git "a/Distributed/DistributeDatabaseDrawEts/figures/\344\277\241.png" "b/Distributed/DistributeDatabaseDrawEts/figures/\344\277\241.png" new file mode 100644 index 0000000000000000000000000000000000000000..49074a428c2308a29171362bf46171d80c8927f0 Binary files /dev/null and "b/Distributed/DistributeDatabaseDrawEts/figures/\344\277\241.png" differ diff --git "a/Distributed/DistributeDatabaseDrawEts/figures/\345\217\226\347\211\210\346\234\254.png" "b/Distributed/DistributeDatabaseDrawEts/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/Distributed/DistributeDatabaseDrawEts/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/Distributed/DistributeDatabaseDrawEts/figures/\346\210\252\345\233\276.png" "b/Distributed/DistributeDatabaseDrawEts/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/Distributed/DistributeDatabaseDrawEts/figures/\346\210\252\345\233\276.png" differ diff --git "a/Distributed/DistributeDatabaseDrawEts/figures/\347\241\256\350\256\244.png" "b/Distributed/DistributeDatabaseDrawEts/figures/\347\241\256\350\256\244.png" new file mode 100644 index 0000000000000000000000000000000000000000..4e8a02292e7dfdc20865a8befb3e23ecf0053222 Binary files /dev/null and "b/Distributed/DistributeDatabaseDrawEts/figures/\347\241\256\350\256\244.png" differ diff --git "a/Distributed/DistributeDatabaseDrawEts/figures/\351\237\263\344\271\220.png" "b/Distributed/DistributeDatabaseDrawEts/figures/\351\237\263\344\271\220.png" new file mode 100644 index 0000000000000000000000000000000000000000..a473a3a4a39363f60b6b36cdd930b23aeeab9445 Binary files /dev/null and "b/Distributed/DistributeDatabaseDrawEts/figures/\351\237\263\344\271\220.png" differ diff --git a/Distributed/DistributeDatabaseDrawEts/gradle/wrapper/gradle-wrapper.jar b/Distributed/DistributeDatabaseDrawEts/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/gradle/wrapper/gradle-wrapper.jar differ diff --git a/Distributed/DistributeDatabaseDrawEts/gradle/wrapper/gradle-wrapper.properties b/Distributed/DistributeDatabaseDrawEts/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..f59159e865d4b59feb1b8c44b001f62fc5d58df4 --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-caution.gif b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-caution.gif differ diff --git a/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-danger.gif b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-danger.gif differ diff --git a/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-note.gif b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-note.gif differ diff --git a/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-notice.gif b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-notice.gif differ diff --git a/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-tip.gif b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-tip.gif differ diff --git a/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-warning.gif b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Distributed/DistributeDatabaseDrawEts/public_sys-resources/icon-warning.gif differ diff --git a/Distributed/DistributeDatabaseDrawEts/settings.gradle b/Distributed/DistributeDatabaseDrawEts/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07 --- /dev/null +++ b/Distributed/DistributeDatabaseDrawEts/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/Distributed/NewsDemo/LICENSE b/Distributed/NewsDemo/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..80576ef141485b36eea4aebf25af97020bc2de44 --- /dev/null +++ b/Distributed/NewsDemo/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + + 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/Distributed/NewsDemo/README.md b/Distributed/NewsDemo/README.md index f9328b762eb74b7cf4ed9d6f681117d607ced307..360f5615d8f305904a318832701856f34059d128 100644 --- a/Distributed/NewsDemo/README.md +++ b/Distributed/NewsDemo/README.md @@ -1,13 +1,342 @@ # NewsDemoOpenHarmony +# 介绍 + +本篇Codelab我们将教会大家如何构建一个简易的OpenHarmony新闻客户端(JS版本)。应用包含两级页面,分别是主页面和详情页面,两个页面都展示了丰富的UI组件,其中详情页的实现逻辑中还展示了如何通过调用相应接口,实现跨设备拉起FA。本教程将结合以下内容进行讲解: + +1.顶部tabs以及新闻列表list的使用 + +2.每条新闻的文本框以及图像 + +3.布局及页面跳转 + +4.设备发现以及跨设备拉起FA + +**最终效果预览如下图所示:** + +![](screenshots/device/zh-cn_image_0000001206445177.png) + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制)。 + +2. 搭建烧录环境: + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境: + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + + 2. 开发环境配置完成后,请参考[使用工程工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](screenshots/device/截图.png) +# 分布式组网 + +完成本篇Codelab我们还需要完成开发板的分布式组网,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. 硬件准备:准备两台烧录相同的版本系统的**Hi3516DV300**开发板A、B。 + +2. 两个开发板A、B配置在同一个WiFi网络之下。 + + 打开设置--\>WLAN--\>点击右侧WiFi开关--\>点击目标WiFi并输入密码。 + + ![](screenshots/device/IMG_20211217_144057.jpg) + +3. 将设备A、B设置为互相信任的设备。 + + - 找到系统应用“音乐”。 + + ![](screenshots/device/音乐.png) + + - 设备A打开音乐,点击左下角带箭头的流转按钮,弹出列表框,在列表中会展示远端设备的id。 + + ![](screenshots/device/IMG_20211213_103011.jpg) + + - 选择远端设备B的id,另一台开发板(设备B)会弹出验证的选项框。 + + ![](screenshots/device/信.png) + + - 设备B点击允许,设备B将会弹出随机PIN码,将设备B的PIN码输入到设备A的PIN码填入框中。 + + ![](screenshots/device/pin.png)![](screenshots/device/确认.png) + + 配网完毕。 + +# 代码结构解读 + +本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在最后的参考中提供下载方式,接下来我们会用一小节来讲解整个工程的代码结构: + +![](screenshots/device/截图1222.png) + +- images:存放工程使用到的图片资源。 +- index:构成新闻列表页面,包括index.hml布局文件、index.css样式文件、index.js逻辑处理文件。 +- detail:构成新闻详情页面,包括detail.hml布局文件、detail.css样式文件、detail.js逻辑处理文件。 +- config.json:配置文件。 + +# 添加主页新闻类型 + +首先为我们的应用添加顶部新闻类型,用于切换不同类别的新闻。这里会使用到tabs、tab-bar控件,同时使用for循环对新闻的title进行遍历,新闻的标题有All、Health、Finance、Technology、Sport、Internet、Game七大类。图片示例和代码如下: + +![](screenshots/device/截图12222.png) + +``` +
+ + + {{ title.name }} + + +
+``` +# 添加主页顶部新闻类型 + +1. 我们需要实现一个新闻item的布局,其样式包含左边的新闻标题、右边的新闻图片以及下方的新闻分割线,图片示例和代码如下: + + ![](screenshots/device/zh-cn_image_0000001238284773.png) + + ``` +
+
+ + {{ news.title }} + + + +
+
+
+
+ ``` + +2. 我们需要实现一个新闻列表,也就是将上方的新闻item进行一个循环的展示,这需要用到list、list-item的相关知识点。我们需要将newsList新闻列表数据进行循环,所以新闻item的布局外层需要嵌套一个list和list-item,图片示例和代码如下: + + ![](screenshots/device/zh-cn_image_0000001193324850.png) + + ``` + + + // 新闻item的布局代码填充到这里 + + + ``` + +3. 我们需要实现新闻类型的切换,每一条新闻都会有一个新闻类型,当选择All的时候默认展示所有类型的新闻,当选择具体的新闻类型时,如选择Health,则需要筛选出属于Health类型的新闻进行展示。添加一个自定义函数changeNewsType,代码如下所示: + + ``` + // 选择新闻类型 + changeNewsType: function (e) { + const type = titles[e.index].name; + this.newsList = []; + if (type === 'All') { + // 展示全部新闻 + this.newsList = newsData; + } else { + // 分类展示新闻 + const newsArray = []; + for (var news of newsData) { + if (news.type === type) { + newsArray.push(news); + } + } + this.newsList = newsArray; + } + } + ``` +# 详情页页面布局 + +详情页面包含新闻标题、阅读量和喜好数、新闻图片、新闻文字以及下方的状态栏。状态栏包括1个可输入文本框和4个功能按键,图片示例和代码如下: + +![](screenshots/device/zh-cn_image_0000001192761736.png) + +``` +
+ {{ title }} + reads: {{ reads }} likes: {{ likes }} + + + {{ content }} + + +
+ + + + + +
+
+``` + +需要注意的是detail.hml只是展示了页面的布局结构,其具体的布局样式需要参考detail.css文件。 + +# 跳转详情页 + +完成新闻列表页面和详情页的布局后,需要实现页面跳转的功能。新闻列表页面中绑定一个list-item的点击事件itemClick,其中传入的参数是news(新闻的详细数据)。 + +``` + +``` + +在JS中页面跳转需要在JS文件的头部引入如下一行代码: + +``` +import router from '@system.router'; +``` + +实现list-item的点击事件itemClick,其代码如下所示: + +``` +itemClick(news) { + // 跳转到详情页面 + router.push({ + uri: 'pages/detail/detail', + params: { + 'title': news.title, + 'type': news.type, + 'imgUrl': news.imgUrl, + 'reads': news.reads, + 'likes': news.likes, + 'content': news.content + } + }); +} +``` +# 设备发现 + +首先给分享按钮添加一个分享事件toShare,代码如下所示: + +``` + +``` + +然后调用getTrustedDeviceListSync\(\),获取所有可信设备的列表,代码如下所示: + +``` +import deviceManager from '@ohos.distributedHardware.deviceManager'; + +toShare() { + // 创建设备管理实例 + deviceManager.createDeviceManager('com.huawei.codelab', (err, data) => { + if (err) { + return; + } + this.deviceMag = data; + // 获取所有可信设备的列表 + this.deviceList = this.deviceMag.getTrustedDeviceListSync(); + }); + // 循环遍历设备列表,获取设备名称和设备Id + for (let i = 0; i < this.deviceList.length; i++) { + this.deviceList[i] = { + deviceName: this.deviceList[i].deviceName, + deviceId: this.deviceList[i].deviceId, + checked: false + }; + } + this.$element('showDialog').show(); + } +``` + +最后自定义dialog弹窗显示所有可信设备,代码如下所示: + +``` + +
+ 选择设备 + + + {{ $item.deviceName }} + + + + + +
+ 取消 + 确定 +
+
+
+``` + +最终实现的效果如下所示: + +![](screenshots/device/截图-0.png) + +>![](screenshots/device/icon-note.gif) **说明:** +>本工程项目包含getTrustedDeviceListSync\(\)获取所有可信设备的列表方法,请选择API 7或以上版本。 +# 分布式拉起 + +弹出设备列表后,选择设备并点击“确定”按钮,将会分布式拉起另外一台设备,其具体实现代码如下所示: + +``` +chooseComform() { + this.$element('showDialog').close(); + for (let i = 0; i < this.deviceList.length; i++) { + // 判断设备是否被选中 + if (this.deviceList[i].checked) { + const params = { + url: 'pages/detail/detail', + title: this.title, + type: this.type, + imgUrl: this.imgUrl, + reads: this.reads, + likes: this.likes, + content: this.content, + }; + + const wantValue = { + bundleName: 'com.huawei.newsdemooh', + abilityName: 'com.huawei.newsdemooh.MainAbility', + deviceId: this.deviceList[i].deviceId, + parameters: params + }; + + featureAbility.startAbility({ + want: wantValue + }).then((data) => { + console.info('featureAbility.startAbility finished, ' + JSON.stringify(data)); + }); + console.info('featureAbility.startAbility want=' + JSON.stringify(wantValue)); + console.info('featureAbility.startAbility end'); + } + } +} +``` +# 回顾和总结 + +本篇Codelab中我们介绍了应用的主页面和详情页。在主页面可以切换新闻类型、滑动新闻列表、点击查看新闻详情;在新闻详情页可以上下滑动查看新闻,并且跨设备拉起。 + +需要说明的是,本篇codelab是采用JS作为主要编程语言,其中分布式的相关实现也是用的JS提供的相关接口来实现的。 +# 恭喜你 + +目前你已经成功完成了Codelab并且学到了: + +- 如何将一个JS项目部署到OpenHarmony设备上。 + +- 如何使用list、list-item、tabs、tab-bar等组件。 +- 如何进行布局编写及页面跳转。 +- 如何进行跨设备分布式拉起。 +# 参考 + +[gitee源码](https://gitee.com/openharmony/codelabs/tree/master/Distributed/NewsDemo) + + + + -NewsDemoOpenHarmony -本篇Codelab是在HarmonyOS 分布式新闻客户端(JAVA)的设计基础上,用JS编程语言重写了一个布局一模一样的新闻客户端,并对OpenHarmony开发板进行了适配。 -Java版本的新闻客户端教会了大家如何使用Java UI中的常用控件、布局编写、页面跳转以及FA的跨设备协同。 -本篇Codelab将使用JS语言进行开发,做一个功能、布局和Java版本完全一样的分布式新闻客户端,大家可以通过这两篇Codelab学习两种编程语言的编码风格和实现区别。 -案例最终效果如下图所示: -![](screenshots/device/NewsClientDemo.PNG) \ No newline at end of file diff --git a/Distributed/NewsDemo/build.gradle b/Distributed/NewsDemo/build.gradle index 0c34fbc0a390a81fdd7c4c98ba1fd97bef4a7fe3..100934a2cd9549dbe84b2048cf0bc72926b7406e 100644 --- a/Distributed/NewsDemo/build.gradle +++ b/Distributed/NewsDemo/build.gradle @@ -6,29 +6,29 @@ ohos { compileSdkVersion 7 supportSystem "standard" } - + buildscript { repositories { maven { - url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/' + url 'https://repo.huaweicloud.com/repository/maven/' } maven { - url 'http://mirrors.tools.huawei.com/maven/' + url 'https://developer.huawei.com/repo/' } } dependencies { - classpath 'com.huawei.ohos:hap:3.0.3.1' + classpath 'com.huawei.ohos:hap:3.0.3.4' classpath 'com.huawei.ohos:decctest:1.2.6.0' } } allprojects { repositories { - maven { - url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/' + maven { + url 'https://repo.huaweicloud.com/repository/maven/' } maven { - url 'http://mirrors.tools.huawei.com/maven/' + url 'https://developer.huawei.com/repo/' } } } diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/app.js b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/app.js deleted file mode 100644 index f03b98f424deab9e9412e6c41863d1d90c60dfb6..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/app.js +++ /dev/null @@ -1,128 +0,0 @@ -/******/ (() => { // webpackBootstrap -/******/ var __webpack_modules__ = ({ - -/***/ "./lib/script.js!./node_modules/babel-loader/lib/index.js?presets[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\preset-env&plugins[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\plugin-transform-modules-commonjs&comments=false!./lib/resource-reference-script.js!./lib/manifest-loader.js?path=D:\\MY\\Hi3516D\\CodeLab\\20210929\\NewsDemo\\entry\\src\\main\\js\\MainAbility\\app.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/app.js": -/*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\ - !*** ./lib/script.js!./node_modules/babel-loader/lib/index.js?presets[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\preset-env&plugins[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\plugin-transform-modules-commonjs&comments=false!./lib/resource-reference-script.js!./lib/manifest-loader.js?path=D:\MY\Hi3516D\CodeLab\20210929\NewsDemo\entry\src\main\js\MainAbility\app.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/app.js ***! - \********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -module.exports = function(module, exports, $app_require$){"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; -var _default = { - onCreate: function onCreate() { - console.info("Application onCreate"); - }, - onDestroy: function onDestroy() { - console.info("Application onDestroy"); - } -}; -exports["default"] = _default; -; -(exports["default"] || module.exports).manifest = __webpack_require__(/*! !!../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/manifest-plugin.js!../../../../.preview/jsManifest/MainAbility/manifest.json */ "./lib/manifest-plugin.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/.preview/jsManifest/MainAbility/manifest.json"); - -function requireModule(moduleName) { - const systemList = ['system.router', 'system.app', 'system.prompt', 'system.configuration', - 'system.image', 'system.device', 'system.mediaquery', 'ohos.animator', 'system.grid', 'system.resource'] - var target = '' - if (systemList.includes(moduleName.replace('@', ''))) { - target = $app_require$('@app-module/' + moduleName.substring(1)); - return target; - } - var shortName = moduleName.replace(/@[^.]+.([^.]+)/, '$1'); - if (typeof ohosplugin !== 'undefined' && /@ohos/.test(moduleName)) { - target = ohosplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - if (typeof systemplugin !== 'undefined') { - target = systemplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - target = requireNapi(shortName); - return target; -} -} -/* generated by ace-loader */ - - -/***/ }), - -/***/ "./lib/manifest-plugin.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/.preview/jsManifest/MainAbility/manifest.json": -/*!***********************************************************************************************************************************!*\ - !*** ./lib/manifest-plugin.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/.preview/jsManifest/MainAbility/manifest.json ***! - \***********************************************************************************************************************************/ -/***/ ((module) => { - -"use strict"; -module.exports = JSON.parse('{"appID":"com.huawei.newsdemo","appName":"$string:entry_MainAbility","versionName":"1.0.0","versionCode":1000000,"minPlatformVersion":7,"pages":["pages/index/index","pages/second/second"],"deviceType":["phone"],"window":{"autoDesignWidth":false,"designWidth":720}}'); - -/***/ }) - -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ // no module.id needed -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. -(() => { -/*!*************************************************************************************************!*\ - !*** ../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/app.js?entry ***! - \*************************************************************************************************/ -var $app_script$ = __webpack_require__(/*! !!../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/script.js!../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/node_modules/babel-loader?presets[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\preset-env&plugins[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\plugin-transform-modules-commonjs&comments=false!../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/resource-reference-script.js!../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/manifest-loader.js?path=D:\MY\Hi3516D\CodeLab\20210929\NewsDemo\entry\src\main\js\MainAbility\app.js!./app.js */ "./lib/script.js!./node_modules/babel-loader/lib/index.js?presets[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\preset-env&plugins[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\plugin-transform-modules-commonjs&comments=false!./lib/resource-reference-script.js!./lib/manifest-loader.js?path=D:\\MY\\Hi3516D\\CodeLab\\20210929\\NewsDemo\\entry\\src\\main\\js\\MainAbility\\app.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/app.js") - - $app_define$('@app-application/app', [], function($app_require$, $app_exports$, $app_module$) { - - $app_script$($app_module$, $app_exports$, $app_require$) - if ($app_exports$.__esModule && $app_exports$.default) { - $app_module$.exports = $app_exports$.default - } - - }) - $app_bootstrap$('@app-application/app',undefined,undefined) -})(); - -/******/ })() -; \ No newline at end of file diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_good.png b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_good.png deleted file mode 100644 index e306e705fe96f10576fa393c3390ea63f26408dd..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_good.png and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_message.png b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_message.png deleted file mode 100644 index b81007d64cbe5265df414a6dab58cd103cd5a521..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_message.png and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_share.png b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_share.png deleted file mode 100644 index 1fb1cae93ea21b0712abc939b828ea92ffcb07f4..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_share.png and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_star.png b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_star.png deleted file mode 100644 index 5ace4c20d2f949b567fc960d205c345273fadee2..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/icon_star.png and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image1.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image1.jpg deleted file mode 100644 index bfe2ae5849d6b022c2eab195f0fc0c04721db285..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image1.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image10.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image10.jpg deleted file mode 100644 index 781936afc0354e0f22d1b77339968927c29ffb36..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image10.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image11.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image11.jpg deleted file mode 100644 index f2862e308f284c5cc87d06c5316d5edec86028f3..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image11.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image12.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image12.jpg deleted file mode 100644 index 0425178705c4e56888d7df2b308efdfcd7ac8640..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image12.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image13.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image13.jpg deleted file mode 100644 index b349d81e1dce2d2a553baaf26a5b7fde58d8beac..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image13.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image14.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image14.jpg deleted file mode 100644 index e3d1ca269b529e890a3e154ac081e93487f5743b..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image14.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image15.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image15.jpg deleted file mode 100644 index 54775977a85c165759a22b8c8e956ecc59603ff8..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image15.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image16.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image16.jpg deleted file mode 100644 index 17780bfc6f7f014b1920fa5159cb1a4699a5de49..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image16.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image17.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image17.jpg deleted file mode 100644 index a34dcd88e1507fd07d509fcffe024dfe7a59ab39..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image17.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image18.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image18.jpg deleted file mode 100644 index ad79353b9bcfb2cd5b05ef6296f29e3ac826d3ca..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image18.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image19.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image19.jpg deleted file mode 100644 index 5e8c9267e9632b829492f6d93bfebfcb9c0dc114..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image19.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image2.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image2.jpg deleted file mode 100644 index 2322f158e6a108b8a4f2bbcb20204bd7974c12d9..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image2.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image3.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image3.jpg deleted file mode 100644 index 6da8be18ed043a9fc815689e7482e9fe04969f1a..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image3.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image4.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image4.jpg deleted file mode 100644 index 78bfe6f367b9534e1236725b50a2b98934a76827..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image4.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image5.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image5.jpg deleted file mode 100644 index bda3780f9779e2169cea6b3cd0aae77bc6e6cc95..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image5.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image6.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image6.jpg deleted file mode 100644 index 60ebfaa4bd05ca32c40b99f247a9d2998d85dd69..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image6.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image7.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image7.jpg deleted file mode 100644 index bfc4fb58e7a5ca3062dc775721f9106d333adaec..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image7.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image8.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image8.jpg deleted file mode 100644 index e58a289f7d136043766f33f168a87af367c370f3..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image8.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image9.jpg b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image9.jpg deleted file mode 100644 index e7de107a86d8a741fa4112c3df79c60a1ac086e5..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/common/images/news_image9.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/manifest.json b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/manifest.json deleted file mode 100644 index 9c28780bfb981944bc50679f81a3279130fb3188..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/manifest.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "appID": "com.huawei.newsdemo", - "appName": "$string:entry_MainAbility", - "versionName": "1.0.0", - "versionCode": 1000000, - "minPlatformVersion": 7, - "pages": [ - "pages/index/index", - "pages/second/second" - ], - "deviceType": [ - "phone" - ], - "window": { - "autoDesignWidth": false, - "designWidth": 720 - } -} \ No newline at end of file diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/pages/index/index.js b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/pages/index/index.js deleted file mode 100644 index 355d0ba65d983c31c0ad7fbf189c99f86088815f..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/pages/index/index.js +++ /dev/null @@ -1,711 +0,0 @@ -/******/ (() => { // webpackBootstrap -/******/ var __webpack_modules__ = ({ - -/***/ "./lib/json.js!./lib/style.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.css": -/*!***************************************************************************************************************************************!*\ - !*** ./lib/json.js!./lib/style.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.css ***! - \***************************************************************************************************************************************/ -/***/ ((module) => { - -module.exports = { - ".container": { - "flexDirection": "column", - "justifyContent": "flex-start", - "alignItems": "center" - }, - ".tab-bar": { - "height": "80px" - }, - ".tab-text": { - "fontSize": "46px", - "textAlign": "center" - }, - ".tab-content": { - "width": "100%", - "height": "100%", - "justifyContent": "center" - }, - ".item-content": { - "height": "100%", - "justifyContent": "center" - }, - ".list": { - "width": "100%", - "paddingTop": "20px", - "paddingRight": "20px", - "paddingBottom": "20px", - "paddingLeft": "20px" - }, - ".text": { - "fontSize": "36px", - "marginTop": "10px", - "marginRight": "10px", - "marginBottom": "10px", - "marginLeft": "10px", - "height": "180px", - "maxLines": "4", - "flexWeight": 3 - }, - ".image": { - "marginTop": "10px", - "marginRight": "10px", - "marginBottom": "10px", - "marginLeft": "10px", - "height": "180px", - "flexWeight": 2 - } -} - -/***/ }), - -/***/ "./lib/json.js!./lib/template.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.hml": -/*!******************************************************************************************************************************************!*\ - !*** ./lib/json.js!./lib/template.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.hml ***! - \******************************************************************************************************************************************/ -/***/ ((module) => { - -module.exports = { - "attr": { - "debugLine": "pages/index/index:1", - "className": "container" - }, - "type": "div", - "classList": [ - "container" - ], - "children": [ - { - "attr": { - "debugLine": "pages/index/index:2", - "index": "0", - "vertical": "false" - }, - "type": "tabs", - "events": { - "change": "changeNewsType" - }, - "children": [ - { - "attr": { - "debugLine": "pages/index/index:3", - "className": "tab-bar", - "mode": "scrollable" - }, - "type": "tab-bar", - "classList": [ - "tab-bar" - ], - "children": [ - { - "attr": { - "debugLine": "pages/index/index:4", - "className": "tab-text", - "value": function () {return this.title.name} - }, - "type": "text", - "classList": [ - "tab-text" - ], - "repeat": { - "exp": function () {return this.titleList}, - "value": "title" - } - } - ] - }, - { - "attr": { - "debugLine": "pages/index/index:7", - "className": "tab-content", - "scrollable": "true" - }, - "type": "tab-content", - "classList": [ - "tab-content" - ], - "children": [ - { - "attr": { - "debugLine": "pages/index/index:8", - "className": "item-content" - }, - "type": "div", - "classList": [ - "item-content" - ], - "repeat": { - "exp": function () {return this.titleList}, - "value": "title" - }, - "children": [ - { - "attr": { - "debugLine": "pages/index/index:9", - "className": "list" - }, - "type": "list", - "classList": [ - "list" - ], - "children": [ - { - "attr": { - "debugLine": "pages/index/index:10" - }, - "type": "list-item", - "repeat": { - "exp": function () {return this.newsList}, - "value": "news" - }, - "onBubbleEvents": { - "click": function (evt) {this.startAbilityContinuation(this.news,evt)} - }, - "children": [ - { - "attr": { - "debugLine": "pages/index/index:11" - }, - "type": "div", - "style": { - "flexDirection": "column" - }, - "children": [ - { - "attr": { - "debugLine": "pages/index/index:13" - }, - "type": "div", - "style": { - "flexDirection": "row" - }, - "children": [ - { - "attr": { - "debugLine": "pages/index/index:14", - "className": "text", - "value": function () {return this.news.title} - }, - "type": "text", - "classList": [ - "text" - ] - }, - { - "attr": { - "debugLine": "pages/index/index:17", - "className": "image", - "src": function () {return this.news.imgUrl} - }, - "type": "image", - "classList": [ - "image" - ] - } - ] - }, - { - "attr": { - "debugLine": "pages/index/index:21" - }, - "type": "div", - "style": { - "height": "2px", - "width": "100%", - "backgroundColor": "#97d2d4d4" - } - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] -} - -/***/ }), - -/***/ "./node_modules/@babel/runtime/helpers/interopRequireDefault.js": -/*!**********************************************************************!*\ - !*** ./node_modules/@babel/runtime/helpers/interopRequireDefault.js ***! - \**********************************************************************/ -/***/ ((module) => { - -"use strict"; - - -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - "default": obj - }; -} - -module.exports = _interopRequireDefault; -module.exports["default"] = module.exports, module.exports.__esModule = true; - -function requireModule(moduleName) { - const systemList = ['system.router', 'system.app', 'system.prompt', 'system.configuration', - 'system.image', 'system.device', 'system.mediaquery', 'ohos.animator', 'system.grid', 'system.resource'] - var target = '' - if (systemList.includes(moduleName.replace('@', ''))) { - target = $app_require$('@app-module/' + moduleName.substring(1)); - return target; - } - var shortName = moduleName.replace(/@[^.]+.([^.]+)/, '$1'); - if (typeof ohosplugin !== 'undefined' && /@ohos/.test(moduleName)) { - target = ohosplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - if (typeof systemplugin !== 'undefined') { - target = systemplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - target = requireNapi(shortName); - return target; -} - - -/***/ }), - -/***/ "./node_modules/@babel/runtime/helpers/newArrowCheck.js": -/*!**************************************************************!*\ - !*** ./node_modules/@babel/runtime/helpers/newArrowCheck.js ***! - \**************************************************************/ -/***/ ((module) => { - -"use strict"; - - -function _newArrowCheck(innerThis, boundThis) { - if (innerThis !== boundThis) { - throw new TypeError("Cannot instantiate an arrow function"); - } -} - -module.exports = _newArrowCheck; -module.exports["default"] = module.exports, module.exports.__esModule = true; - -function requireModule(moduleName) { - const systemList = ['system.router', 'system.app', 'system.prompt', 'system.configuration', - 'system.image', 'system.device', 'system.mediaquery', 'ohos.animator', 'system.grid', 'system.resource'] - var target = '' - if (systemList.includes(moduleName.replace('@', ''))) { - target = $app_require$('@app-module/' + moduleName.substring(1)); - return target; - } - var shortName = moduleName.replace(/@[^.]+.([^.]+)/, '$1'); - if (typeof ohosplugin !== 'undefined' && /@ohos/.test(moduleName)) { - target = ohosplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - if (typeof systemplugin !== 'undefined') { - target = systemplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - target = requireNapi(shortName); - return target; -} - - -/***/ }), - -/***/ "./lib/script.js!./node_modules/babel-loader/lib/index.js?presets[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\preset-env&plugins[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\plugin-transform-modules-commonjs&comments=false!./lib/resource-reference-script.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.js": -/*!***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\ - !*** ./lib/script.js!./node_modules/babel-loader/lib/index.js?presets[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\preset-env&plugins[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\plugin-transform-modules-commonjs&comments=false!./lib/resource-reference-script.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.js ***! - \***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -module.exports = function(module, exports, $app_require$){"use strict"; - -var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _newArrowCheck2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/newArrowCheck */ "./node_modules/@babel/runtime/helpers/newArrowCheck.js")); - -var _ohosAbility = _interopRequireDefault(requireModule("@ohos.ability.featureAbility")); - -function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } - -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - -var titles = [{ - "name": "All" -}, { - "name": "Health" -}, { - "name": "Finance" -}, { - "name": "Technology" -}, { - "name": "Sport" -}, { - "name": "Internet" -}, { - "name": "Game" -}]; -var newsData = [{ - "title": "Best Enterprise Wi-Fi Network Award of the Wireless Broadband Alliance 2020", - "type": "Health", - "imgUrl": "/common/images/news_image1.jpg", - "reads": "54", - "likes": "81", - "content": "Recently, at the Wireless Broadband Alliance (WBA), an international industry organization, Huawei's AirEngine Wi-Fi 6 Solution Helps Factory Digital Transformation WBA 2020 Wi-Fi Industry Best Enterprise Wi-Fi Network Award. This is the first time that a Chinese Wi-Fi 6 vendor has won this award, which reflects the full recognition of Huawei AirEngine Wi-Fi 6 by global enterprise users." -}, { - "title": "Latest technology and industry weather vane", - "type": "Health", - "imgUrl": "/common/images/news_image2.jpg", - "reads": "100", - "likes": "354", - "content": "With the large-scale commercial use of new technologies such as 5G, IoT, cloud computing, and AI, industry digital transformation has entered deep water. In addition, the sudden epidemic and carbon-neutral targets accelerate the transformation of society towards intelligence. When energy technologies are combined with power electronics and digital technologies, what direction will site energy develop?" -}, { - "title": "Openness and Cooperation Facilitate Industry Upgrade", - "type": "Finance", - "imgUrl": "/common/images/news_image3.jpg", - "reads": "74", - "likes": "91", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." -}, { - "title": "High-voltage super-fast charging is an inevitable trend", - "type": "Finance", - "imgUrl": "/common/images/news_image4.jpg", - "reads": "44", - "likes": "82", - "content": "Consumers have a lot of doubts about buying electric cars, compared to fuel cars. Wang Chao pointed out that among the factors affecting the purchase of electric vehicles, charging problems account for 80 percent, with a small number of charging piles (currently, the ratio of piles is 3.2:1) and a long charging time being the first to bear the brunt. As a result, many players in the charging infrastructure sector are looking for a break. To alleviate consumers' pain points of poor charging experience, we need to improve the pile ratio and shorten the charging time to meet consumers' requirements for fast charging." -}, { - "title": "Huawei Releases the New Trend of Modular Power Supply, Facilitating Industry Upgrade Through Open Cooperation", - "type": "Technology", - "imgUrl": "/common/images/news_image5.jpg", - "reads": "73", - "likes": "888", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh. There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." -}, { - "title": "Ten Future Trends of Digital Energy", - "type": "Technology", - "imgUrl": "/common/images/news_image6.jpg", - "reads": "100", - "likes": "354", - "content": "Energy digitalization is an inevitable trend. Innovative integration of digital and energy technologies enables end-to-end visual, manageable, and controllable intelligent management of energy infrastructure, improving energy efficiency.\nGreen power will benefit thousands of industries and households in the future. Green power, represented by PV, will become the main energy source. The era of price-effective PV is coming, and the integration of distributed power generation and solar storage will become an inevitable trend. Green Power will also help the ICT industry reduce its carbon footprint. In the future, we will build a \"zero-carbon network\" and \"zero-carbon\" data center. In addition, Huawei proposed the trend of full-link efficiency for the first time and implemented global optimization in terms of architecture and system." -}, { - "title": "Ascend Helps Industry, Learning, and Research Promote AI Industry Development in the National AI Contest", - "type": "Sport", - "imgUrl": "/common/images/news_image7.jpg", - "reads": "123", - "likes": "911", - "content": "The holding of the National AI Contest further fulfilled the requirements of the Ministry of Science and Technology and the Ministry of Industry and Information Technology for Shenzhen to build the national new-generation AI innovation and development trial zone and the AI innovation and application pilot zone. It also promoted the integration and development of innovation elements such as industry, academia, capital, and talent, create an AI innovation atmosphere. Huawei has co-hosted two National AI Competitions in a row, aiming to promote technological progress, industrial upgrade, economic transformation, and social progress, and jointly promote the implementation of AI technologies. This is the most practical point for Huawei and the National AI Competition." -}, { - "title": "Enterprise data centers are moving towards autonomous driving network", - "type": "Sport", - "imgUrl": "/common/images/news_image8.jpg", - "reads": "754", - "likes": "149", - "content": "More than 90% of enterprises say that fully autonomous driving data center network is their goal to achieve business agility, flexibility, and cost-effectiveness. This is a key research result in the data center network Autonomous Driving Index Report released by Huawei and IDC. Autonomous driving data center network helps enterprises restructure network architectures and operation models and enhance business resilience and continuity. In addition, regardless of the current level of data center network automation, IDC offers some guidance on how enterprises can move forward and move towards full automation." -}, { - "title": "One optical fiber lights up a green smart room", - "type": "Internet", - "imgUrl": "/common/images/news_image9.jpg", - "reads": "631", - "likes": "714", - "content": "At the 2020 China Real Estate Development Summit held in Guangzhou, Jin Yuzhi, President of Huawei's Transmission and Access Product Line, delivered a keynote speech entitled \"One Fiber Lights Green Smart Rooms\" to discuss the convergence development trend of optical networks and real estate industries, proposes that optical fibers are the standard configuration of F5G smart real estate, and shares seven reasons for choosing Fiber to the Room (FTTR) all-optical home networking, we call on industry partners to work together to build an F5G real gigabit all-optical room ecosystem." -}, { - "title": "BWS2020: Accelerate Network Autonomy and Enable Agile Business", - "type": "Internet", - "imgUrl": "/common/images/news_image10.jpg", - "reads": "53", - "likes": "824", - "content": "Currently, millions of enterprises embrace changes and accelerate their cloudification. SaaS traffic surges. Enterprise cloudification and multi-cloud collaboration become the new focus of cloud-network synergy . To address this challenge, Guo Dazheng, president of Huawei's data communications field, said: \"In cloud-network scenarios, iMaster NCE implements network as a service to help carriers provide cloud-network integration services and meet enterprise cloud access requirements.\" In 5G transport scenarios, improve the automation capability of the entire process of planning, construction, maintenance, and optimization to meet the requirements of large-scale 5G network construction and cloud network cost reduction and efficiency improvement." -}, { - "title": "Trust technology, embrace openness, and share the world prosperity brought by technology", - "type": "Game", - "imgUrl": "/common/images/news_image11.jpg", - "reads": "1500", - "likes": "3542", - "content": "Huawei successfully held the TrustInTech 2020 online summit today. Ryan Ding, Executive Director of Huawei, President of the Carrier BG, and Jim Rogers, a senior Wall Street investor, GSMA Chief Marketing Officer Stephanie Lynch-Habib and other ICT industry experts and economists from around the world attended the summit. The summit pointed out that ICT has become a digital foundation for economic development and people's livelihood. In an era of accelerated commercial use of 5G, the world needs to embrace openness and cooperation to eliminate unnecessary resistance and fears about new technologies and transnational cooperation, thereby sharing the world prosperity brought by technology." -}, { - "title": "Intelligent Twins Won the Leading Technology Achievement Award at the 7th World Internet Conference", - "type": "Game", - "imgUrl": "/common/images/news_image12.jpg", - "reads": "7451", - "likes": "9511", - "content": "Today, the Leading Technology Award was unveiled at the 7th World Internet Conference. As the industry's first systematic technical reference architecture for government and enterprise intelligence upgrade, intelligent virtual appliances have been recognized by experts and judges and won the Leading Scientific Achievement Award for their exploration and practice in various industries. This is the fifth time Huawei has won this award since 2016. The World Internet Leading Science and Technology Award showcases the latest technologies in the global ICT field and focuses on the best practices of innovative technologies in the fields of science and technology fight against epidemics, recovery of work, and promotion of digital economic development and cooperation." -}, { - "title": "4G/5G FWA, New Engine for Revenue Growth", - "type": "Health", - "imgUrl": "/common/images/news_image13.jpg", - "reads": "445", - "likes": "872", - "content": "The reason why FWA is growing so fast is that it provides new opportunities for carriers in the consumer market. For example, a Philippine operator used 4G FWA to rapidly develop home broadband users. According to its third quarter financial report, the operator has successfully developed 2.78 million new users this year, accounting for 80% of the total broadband users. The percentage of broadband revenue increased from 12.3% in 2017 to 17.9%. With the development of wireless technologies, 5G FWA can provide gigabit home access experience similar to that of optical fibers, meeting services such as 4K/8K HD video and AR/VR interactive experience." -}, { - "title": "Down! CPI released in November! These things are cheap", - "type": "Finance", - "imgUrl": "/common/images/news_image14.jpg", - "reads": "734", - "likes": "8788", - "content": "Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap." -}, { - "title": "Comedy movie \"Big Red Envelope\" is set to celebrate the New Year", - "type": "Technology", - "imgUrl": "/common/images/news_image15.jpg", - "reads": "1010", - "likes": "3534", - "content": "Comedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New Year" -}, { - "title": "Three living things are smart", - "type": "Sport", - "imgUrl": "/common/images/news_image16.jpg", - "reads": "1243", - "likes": "9141", - "content": "Lifan said at the press conference: \"Retrospective on the journey, we have always adhered to the spirit of initiative, innovation and science. Build core capabilities in terms of networks, technologies, and platforms, and deliver excellent services, technologies, and quality. Internal maintenance, optimization, and sharing are in place. Carriers, equipment vendors, and partners are working together to build an end-to-end network capability and win-win ecosystem to provide users with the best 5G experience and services.\"" -}, { - "title": "Maximizing the Value of Wireless Networks and Ushering in the Golden Decade of 5G", - "type": "Internet", - "imgUrl": "/common/images/news_image17.jpg", - "reads": "7574", - "likes": "1439", - "content": "The 5G industry is developing faster than the previous standards. Currently, there are more than 100 5G commercial networks around the world, and the price of entry-level 5G mobile phones has fallen to CNY1,000, which has led to the rapid growth of 5G users worldwide. Thanks to this, leading operators have enjoyed the data dividend brought by 5G. The multi-dimensional package design and 5G message and 5G new communication services are upgraded to increase the ARPU of 5G users to different degrees.\nTo promote the further development of 5G networks and encourage more users to choose and prefer 5G networks, operators need to build 5G top-quality networks for individual users to achieve full-scenario coverage in densely populated urban areas, suburban areas, and indoor areas, allowing mobile phone users to access 5G services anytime, anywhere. In addition, 5G connection experience is optimized to ensure consistent user experience." -}, { - "title": "Technology Helps Art, Leads a New Era", - "type": "Game", - "imgUrl": "/common/images/news_image18.jpg", - "reads": "6311", - "likes": "7114", - "content": "Zhang Wenlin spoke highly of the \"Dance Storm\". He believes that since the second season's premiere, the show has brought the contestants' exquisite dance moves, the wonderful host of Mr Ho Kung, the excellent comments of the judges' tutors, and the exquisite design of the staff to the audience, dedicate a beautiful visual feast! To help achieve fantastic visual effects, Hunan Radio and TV set up a joint team with Huawei to develop a spatio-temporal condensation system for Dance Storm 2. The system supports AI algorithms such as intelligent fast focusing, butterfly shooting, zoom-in, and multi-focus, with the help of the video 3.0+ platform of device-cloud synergy, the program team has made several industry-leading achievements, such as the three-dimensional storm moment with fantastic visual changes, free-view Dance Storm program with interactive control and rotation, and dance Storm with 360-degree panoramic view. VR programs." -}, { - "title": "Open Intelligent Twin Ecosystem Is the Key to All-Scenario Intelligence", - "type": "Health", - "imgUrl": "/common/images/news_image19.jpg", - "reads": "6341", - "likes": "7164", - "content": "Intelligent upgrade will build core competitiveness in various industries. Huawei works with partners to integrate 5G, cloud, AI, intelligent edge, and industry applications to form an integrated intelligent system and create industry-leading smart experience. In the transportation industry, the abolition of highway toll stations at the provincial boundary enables fast and insensitive traffic, greatly improving traffic efficiency and reducing logistics transportation costs. Intelligent cameras are deployed on highway portals to collect vehicle traffic data 24 hours a day and send the data to the cloud in real time over the high-speed network for real-time charging. In addition, AI models trained on the cloud can be pushed to the edge so that cameras can have capabilities such as license plate recognition and vehicle feature extraction, and the capabilities can be continuously evolved. For example, in extreme weather conditions such as rain and snow, one-click upgrade can be performed on the cloud." -}]; -var _default = { - data: function data() { - return { - titleList: titles, - newsList: newsData - }; - }, - onInit: function onInit() { - console.log("onInit::" + titles); - }, - changeNewsType: function changeNewsType(e) { - var type = titles[e.index].name; - this.newsList = []; - - if (type === "All") { - this.newsList = newsData; - } else { - var newsArray = []; - - var _iterator = _createForOfIteratorHelper(newsData), - _step; - - try { - for (_iterator.s(); !(_step = _iterator.n()).done;) { - var news = _step.value; - - if (news.type === type) { - newsArray.push(news); - } - } - } catch (err) { - _iterator.e(err); - } finally { - _iterator.f(); - } - - this.newsList = newsArray; - } - }, - startAbilityContinuation: function startAbilityContinuation(news) { - var _this = this; - - var params; - params = { - title: news.title, - type: news.type, - imgUrl: news.imgUrl, - reads: news.reads, - likes: news.likes, - content: news.content - }; - var wantValue = { - bundleName: 'com.example.newsclientopenharmony', - abilityName: 'com.example.newsclientopenharmony.MainAbility2', - deviceId: '', - parameters: params - }; - - _ohosAbility["default"].startAbility({ - want: wantValue - }).then(function (data) { - (0, _newArrowCheck2["default"])(this, _this); - console.info('featureAbility.startAbility finished, ' + JSON.stringify(data)); - }.bind(this)); - - console.info('featureAbility.startAbility want=' + JSON.stringify(wantValue)); - console.info('featureAbility.startAbility end'); - } -}; -exports["default"] = _default; - -function requireModule(moduleName) { - const systemList = ['system.router', 'system.app', 'system.prompt', 'system.configuration', - 'system.image', 'system.device', 'system.mediaquery', 'ohos.animator', 'system.grid', 'system.resource'] - var target = '' - if (systemList.includes(moduleName.replace('@', ''))) { - target = $app_require$('@app-module/' + moduleName.substring(1)); - return target; - } - var shortName = moduleName.replace(/@[^.]+.([^.]+)/, '$1'); - if (typeof ohosplugin !== 'undefined' && /@ohos/.test(moduleName)) { - target = ohosplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - if (typeof systemplugin !== 'undefined') { - target = systemplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - target = requireNapi(shortName); - return target; -} - -var moduleOwn = exports.default || module.exports; -var accessors = ['public', 'protected', 'private']; -if (moduleOwn.data && accessors.some(function (acc) { - return moduleOwn[acc]; - })) { - throw new Error('For VM objects, attribute data must not coexist with public, protected, or private. Please replace data with public.'); -} else if (!moduleOwn.data) { - moduleOwn.data = {}; - moduleOwn._descriptor = {}; - accessors.forEach(function(acc) { - var accType = typeof moduleOwn[acc]; - if (accType === 'object') { - moduleOwn.data = Object.assign(moduleOwn.data, moduleOwn[acc]); - for (var name in moduleOwn[acc]) { - moduleOwn._descriptor[name] = {access : acc}; - } - } else if (accType === 'function') { - console.warn('For VM objects, attribute ' + acc + ' value must not be a function. Change the value to an object.'); - } - }); -}} -/* generated by ace-loader */ - - -/***/ }) - -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ // no module.id needed -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. -(() => { -/*!****************************************************************************************************************!*\ - !*** ../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.hml?entry ***! - \****************************************************************************************************************/ -var $app_template$ = __webpack_require__(/*! !!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/json.js!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/template.js!./index.hml */ "./lib/json.js!./lib/template.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.hml") -var $app_style$ = __webpack_require__(/*! !!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/json.js!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/style.js!./index.css */ "./lib/json.js!./lib/style.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.css") -var $app_script$ = __webpack_require__(/*! !!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/script.js!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/node_modules/babel-loader?presets[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\preset-env&plugins[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\plugin-transform-modules-commonjs&comments=false!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/resource-reference-script.js!./index.js */ "./lib/script.js!./node_modules/babel-loader/lib/index.js?presets[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\preset-env&plugins[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\plugin-transform-modules-commonjs&comments=false!./lib/resource-reference-script.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.js") - -$app_define$('@app-component/index', [], function($app_require$, $app_exports$, $app_module$) { - -$app_script$($app_module$, $app_exports$, $app_require$) -if ($app_exports$.__esModule && $app_exports$.default) { -$app_module$.exports = $app_exports$.default -} - -$app_module$.exports.template = $app_template$ - -$app_module$.exports.style = $app_style$ - -}) -$app_bootstrap$('@app-component/index',undefined,undefined) -})(); - -/******/ })() -; \ No newline at end of file diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/pages/second/second.js b/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/pages/second/second.js deleted file mode 100644 index 518590594b4152231782bc5a83b5841131470c4a..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/pages/second/second.js +++ /dev/null @@ -1,290 +0,0 @@ -/******/ (() => { // webpackBootstrap -/******/ var __webpack_modules__ = ({ - -/***/ "./lib/json.js!./lib/style.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/second/second.css": -/*!*****************************************************************************************************************************************!*\ - !*** ./lib/json.js!./lib/style.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/second/second.css ***! - \*****************************************************************************************************************************************/ -/***/ ((module) => { - -module.exports = { - ".container": { - "display": "flex", - "flexDirection": "column", - "justifyContent": "center", - "alignItems": "center", - "left": "0px", - "top": "0px", - "width": "100%", - "height": "100%" - }, - ".title": { - "fontSize": "60px", - "textAlign": "center", - "width": "100%", - "height": "40%", - "marginTop": "10px", - "marginRight": "10px", - "marginBottom": "10px", - "marginLeft": "10px" - }, - ".btn": { - "width": "50%", - "height": "100px", - "fontSize": "40px" - } -} - -/***/ }), - -/***/ "./lib/json.js!./lib/template.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/second/second.hml": -/*!********************************************************************************************************************************************!*\ - !*** ./lib/json.js!./lib/template.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/second/second.hml ***! - \********************************************************************************************************************************************/ -/***/ ((module) => { - -module.exports = { - "attr": { - "debugLine": "pages/second/second:1", - "className": "container" - }, - "type": "div", - "classList": [ - "container" - ], - "children": [ - { - "attr": { - "debugLine": "pages/second/second:2", - "className": "title", - "value": function () {return this.$t('strings.page')} - }, - "type": "text", - "classList": [ - "title" - ] - }, - { - "attr": { - "debugLine": "pages/second/second:5", - "className": "btn", - "type": "button", - "value": function () {return this.$t('strings.back')} - }, - "type": "input", - "classList": [ - "btn" - ], - "onBubbleEvents": { - "click": "onclick" - } - } - ] -} - -/***/ }), - -/***/ "./node_modules/@babel/runtime/helpers/interopRequireDefault.js": -/*!**********************************************************************!*\ - !*** ./node_modules/@babel/runtime/helpers/interopRequireDefault.js ***! - \**********************************************************************/ -/***/ ((module) => { - -"use strict"; - - -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - "default": obj - }; -} - -module.exports = _interopRequireDefault; -module.exports["default"] = module.exports, module.exports.__esModule = true; - -function requireModule(moduleName) { - const systemList = ['system.router', 'system.app', 'system.prompt', 'system.configuration', - 'system.image', 'system.device', 'system.mediaquery', 'ohos.animator', 'system.grid', 'system.resource'] - var target = '' - if (systemList.includes(moduleName.replace('@', ''))) { - target = $app_require$('@app-module/' + moduleName.substring(1)); - return target; - } - var shortName = moduleName.replace(/@[^.]+.([^.]+)/, '$1'); - if (typeof ohosplugin !== 'undefined' && /@ohos/.test(moduleName)) { - target = ohosplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - if (typeof systemplugin !== 'undefined') { - target = systemplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - target = requireNapi(shortName); - return target; -} - - -/***/ }), - -/***/ "./lib/script.js!./node_modules/babel-loader/lib/index.js?presets[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\preset-env&plugins[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\plugin-transform-modules-commonjs&comments=false!./lib/resource-reference-script.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/second/second.js": -/*!*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\ - !*** ./lib/script.js!./node_modules/babel-loader/lib/index.js?presets[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\preset-env&plugins[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\plugin-transform-modules-commonjs&comments=false!./lib/resource-reference-script.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/second/second.js ***! - \*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -module.exports = function(module, exports, $app_require$){"use strict"; - -var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _system = _interopRequireDefault(requireModule("@system.router")); - -var _default = { - data: { - title: 'World' - }, - onclick: function onclick() { - _system["default"].replace({ - uri: "pages/index/index" - }); - } -}; -exports["default"] = _default; - -function requireModule(moduleName) { - const systemList = ['system.router', 'system.app', 'system.prompt', 'system.configuration', - 'system.image', 'system.device', 'system.mediaquery', 'ohos.animator', 'system.grid', 'system.resource'] - var target = '' - if (systemList.includes(moduleName.replace('@', ''))) { - target = $app_require$('@app-module/' + moduleName.substring(1)); - return target; - } - var shortName = moduleName.replace(/@[^.]+.([^.]+)/, '$1'); - if (typeof ohosplugin !== 'undefined' && /@ohos/.test(moduleName)) { - target = ohosplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - if (typeof systemplugin !== 'undefined') { - target = systemplugin; - for (let key of shortName.split('.')) { - target = target[key]; - if(!target) { - break; - } - } - if (typeof target !== 'undefined') { - return target; - } - } - target = requireNapi(shortName); - return target; -} - -var moduleOwn = exports.default || module.exports; -var accessors = ['public', 'protected', 'private']; -if (moduleOwn.data && accessors.some(function (acc) { - return moduleOwn[acc]; - })) { - throw new Error('For VM objects, attribute data must not coexist with public, protected, or private. Please replace data with public.'); -} else if (!moduleOwn.data) { - moduleOwn.data = {}; - moduleOwn._descriptor = {}; - accessors.forEach(function(acc) { - var accType = typeof moduleOwn[acc]; - if (accType === 'object') { - moduleOwn.data = Object.assign(moduleOwn.data, moduleOwn[acc]); - for (var name in moduleOwn[acc]) { - moduleOwn._descriptor[name] = {access : acc}; - } - } else if (accType === 'function') { - console.warn('For VM objects, attribute ' + acc + ' value must not be a function. Change the value to an object.'); - } - }); -}} -/* generated by ace-loader */ - - -/***/ }) - -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ // no module.id needed -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. -(() => { -/*!******************************************************************************************************************!*\ - !*** ../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/second/second.hml?entry ***! - \******************************************************************************************************************/ -var $app_template$ = __webpack_require__(/*! !!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/json.js!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/template.js!./second.hml */ "./lib/json.js!./lib/template.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/second/second.hml") -var $app_style$ = __webpack_require__(/*! !!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/json.js!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/style.js!./second.css */ "./lib/json.js!./lib/style.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/second/second.css") -var $app_script$ = __webpack_require__(/*! !!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/script.js!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/node_modules/babel-loader?presets[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\preset-env&plugins[]=D:\MY\Hi3516D\SDK\version-Daily_Version-20210926_102043-ohos-sdk-LTS\windows\js\3.0.0.0\build-tools\ace-loader\node_modules\@babel\plugin-transform-modules-commonjs&comments=false!../../../../../../../../../../SDK/version-Daily_Version-20210926_102043-ohos-sdk-LTS/windows/js/3.0.0.0/build-tools/ace-loader/lib/resource-reference-script.js!./second.js */ "./lib/script.js!./node_modules/babel-loader/lib/index.js?presets[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\preset-env&plugins[]=D:\\MY\\Hi3516D\\SDK\\version-Daily_Version-20210926_102043-ohos-sdk-LTS\\windows\\js\\3.0.0.0\\build-tools\\ace-loader\\node_modules\\@babel\\plugin-transform-modules-commonjs&comments=false!./lib/resource-reference-script.js!../../../../../../../CodeLab/20210929/NewsDemo/entry/src/main/js/MainAbility/pages/second/second.js") - -$app_define$('@app-component/second', [], function($app_require$, $app_exports$, $app_module$) { - -$app_script$($app_module$, $app_exports$, $app_require$) -if ($app_exports$.__esModule && $app_exports$.default) { -$app_module$.exports = $app_exports$.default -} - -$app_module$.exports.template = $app_template$ - -$app_module$.exports.style = $app_style$ - -}) -$app_bootstrap$('@app-component/second',undefined,undefined) -})(); - -/******/ })() -; \ No newline at end of file diff --git a/Distributed/NewsDemo/entry/.preview/jsManifest/MainAbility/manifest.json b/Distributed/NewsDemo/entry/.preview/jsManifest/MainAbility/manifest.json deleted file mode 100644 index 9c28780bfb981944bc50679f81a3279130fb3188..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/.preview/jsManifest/MainAbility/manifest.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "appID": "com.huawei.newsdemo", - "appName": "$string:entry_MainAbility", - "versionName": "1.0.0", - "versionCode": 1000000, - "minPlatformVersion": 7, - "pages": [ - "pages/index/index", - "pages/second/second" - ], - "deviceType": [ - "phone" - ], - "window": { - "autoDesignWidth": false, - "designWidth": 720 - } -} \ No newline at end of file diff --git a/Distributed/NewsDemo/entry/.preview/merge_js_src/liteWearable/default/pages/index/index.js b/Distributed/NewsDemo/entry/.preview/merge_js_src/liteWearable/default/pages/index/index.js deleted file mode 100644 index 4a9d8d96cdc0c51dedc0d6d5f530c7b2a8716a0d..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/.preview/merge_js_src/liteWearable/default/pages/index/index.js +++ /dev/null @@ -1,264 +0,0 @@ -//import {titles, newsData} from '../../../MainAbility/common/data/data.js'; - -import featureAbility from '@ohos.ability.featureAbility'; - - const titles= [ - { - "name": "All" - }, - { - "name": "Health" - }, - { - "name": "Finance" - }, - { - "name": "Technology" - }, - { - "name": "Sport" - }, - { - "name": "Internet" - }, - { - "name": "Game" - } -] - - const newsData = [ - { - "title": "Best Enterprise Wi-Fi Network Award of the Wireless Broadband Alliance 2020", - "type": "Health", - "imgUrl": "/common/images/news_image1.jpg", - "reads": "54", - "likes": "81", - "content": "Recently, at the Wireless Broadband Alliance (WBA), an international industry organization, Huawei's AirEngine Wi-Fi 6 Solution Helps Factory Digital Transformation WBA 2020 Wi-Fi Industry Best Enterprise Wi-Fi Network Award. This is the first time that a Chinese Wi-Fi 6 vendor has won this award, which reflects the full recognition of Huawei AirEngine Wi-Fi 6 by global enterprise users." - }, - { - "title": "Latest technology and industry weather vane", - "type": "Health", - "imgUrl": "/common/images/news_image2.jpg", - "reads": "100", - "likes": "354", - "content": "With the large-scale commercial use of new technologies such as 5G, IoT, cloud computing, and AI, industry digital transformation has entered deep water. In addition, the sudden epidemic and carbon-neutral targets accelerate the transformation of society towards intelligence. When energy technologies are combined with power electronics and digital technologies, what direction will site energy develop?" - }, - { - "title": "Openness and Cooperation Facilitate Industry Upgrade", - "type": "Finance", - "imgUrl": "/common/images/news_image3.jpg", - "reads": "74", - "likes": "91", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." - }, - { - "title": "High-voltage super-fast charging is an inevitable trend", - "type": "Finance", - "imgUrl": "/common/images/news_image4.jpg", - "reads": "44", - "likes": "82", - "content": "Consumers have a lot of doubts about buying electric cars, compared to fuel cars. Wang Chao pointed out that among the factors affecting the purchase of electric vehicles, charging problems account for 80 percent, with a small number of charging piles (currently, the ratio of piles is 3.2:1) and a long charging time being the first to bear the brunt. As a result, many players in the charging infrastructure sector are looking for a break. To alleviate consumers' pain points of poor charging experience, we need to improve the pile ratio and shorten the charging time to meet consumers' requirements for fast charging." - }, - { - "title": "Huawei Releases the New Trend of Modular Power Supply, Facilitating Industry Upgrade Through Open Cooperation", - "type": "Technology", - "imgUrl": "/common/images/news_image5.jpg", - "reads": "73", - "likes": "888", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh. There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." - }, - { - "title": "Ten Future Trends of Digital Energy", - "type": "Technology", - "imgUrl": "/common/images/news_image6.jpg", - "reads": "100", - "likes": "354", - "content": "Energy digitalization is an inevitable trend. Innovative integration of digital and energy technologies enables end-to-end visual, manageable, and controllable intelligent management of energy infrastructure, improving energy efficiency.\nGreen power will benefit thousands of industries and households in the future. Green power, represented by PV, will become the main energy source. The era of price-effective PV is coming, and the integration of distributed power generation and solar storage will become an inevitable trend. Green Power will also help the ICT industry reduce its carbon footprint. In the future, we will build a \"zero-carbon network\" and \"zero-carbon\" data center. In addition, Huawei proposed the trend of full-link efficiency for the first time and implemented global optimization in terms of architecture and system." - }, - { - "title": "Ascend Helps Industry, Learning, and Research Promote AI Industry Development in the National AI Contest", - "type": "Sport", - "imgUrl": "/common/images/news_image7.jpg", - "reads": "123", - "likes": "911", - "content": "The holding of the National AI Contest further fulfilled the requirements of the Ministry of Science and Technology and the Ministry of Industry and Information Technology for Shenzhen to build the national new-generation AI innovation and development trial zone and the AI innovation and application pilot zone. It also promoted the integration and development of innovation elements such as industry, academia, capital, and talent, create an AI innovation atmosphere. Huawei has co-hosted two National AI Competitions in a row, aiming to promote technological progress, industrial upgrade, economic transformation, and social progress, and jointly promote the implementation of AI technologies. This is the most practical point for Huawei and the National AI Competition." - }, - { - "title": "Enterprise data centers are moving towards autonomous driving network", - "type": "Sport", - "imgUrl": "/common/images/news_image8.jpg", - "reads": "754", - "likes": "149", - "content": "More than 90% of enterprises say that fully autonomous driving data center network is their goal to achieve business agility, flexibility, and cost-effectiveness. This is a key research result in the data center network Autonomous Driving Index Report released by Huawei and IDC. Autonomous driving data center network helps enterprises restructure network architectures and operation models and enhance business resilience and continuity. In addition, regardless of the current level of data center network automation, IDC offers some guidance on how enterprises can move forward and move towards full automation." - }, - { - "title": "One optical fiber lights up a green smart room", - "type": "Internet", - "imgUrl": "/common/images/news_image9.jpg", - "reads": "631", - "likes": "714", - "content": "At the 2020 China Real Estate Development Summit held in Guangzhou, Jin Yuzhi, President of Huawei's Transmission and Access Product Line, delivered a keynote speech entitled \"One Fiber Lights Green Smart Rooms\" to discuss the convergence development trend of optical networks and real estate industries, proposes that optical fibers are the standard configuration of F5G smart real estate, and shares seven reasons for choosing Fiber to the Room (FTTR) all-optical home networking, we call on industry partners to work together to build an F5G real gigabit all-optical room ecosystem." - }, - { - "title": "BWS2020: Accelerate Network Autonomy and Enable Agile Business", - "type": "Internet", - "imgUrl": "/common/images/news_image10.jpg", - "reads": "53", - "likes": "824", - "content": "Currently, millions of enterprises embrace changes and accelerate their cloudification. SaaS traffic surges. Enterprise cloudification and multi-cloud collaboration become the new focus of cloud-network synergy . To address this challenge, Guo Dazheng, president of Huawei's data communications field, said: \"In cloud-network scenarios, iMaster NCE implements network as a service to help carriers provide cloud-network integration services and meet enterprise cloud access requirements.\" In 5G transport scenarios, improve the automation capability of the entire process of planning, construction, maintenance, and optimization to meet the requirements of large-scale 5G network construction and cloud network cost reduction and efficiency improvement." - }, - { - "title": "Trust technology, embrace openness, and share the world prosperity brought by technology", - "type": "Game", - "imgUrl": "/common/images/news_image11.jpg", - "reads": "1500", - "likes": "3542", - "content": "Huawei successfully held the TrustInTech 2020 online summit today. Ryan Ding, Executive Director of Huawei, President of the Carrier BG, and Jim Rogers, a senior Wall Street investor, GSMA Chief Marketing Officer Stephanie Lynch-Habib and other ICT industry experts and economists from around the world attended the summit. The summit pointed out that ICT has become a digital foundation for economic development and people's livelihood. In an era of accelerated commercial use of 5G, the world needs to embrace openness and cooperation to eliminate unnecessary resistance and fears about new technologies and transnational cooperation, thereby sharing the world prosperity brought by technology." - }, - { - "title": "Intelligent Twins Won the Leading Technology Achievement Award at the 7th World Internet Conference", - "type": "Game", - "imgUrl": "/common/images/news_image12.jpg", - "reads": "7451", - "likes": "9511", - "content": "Today, the Leading Technology Award was unveiled at the 7th World Internet Conference. As the industry's first systematic technical reference architecture for government and enterprise intelligence upgrade, intelligent virtual appliances have been recognized by experts and judges and won the Leading Scientific Achievement Award for their exploration and practice in various industries. This is the fifth time Huawei has won this award since 2016. The World Internet Leading Science and Technology Award showcases the latest technologies in the global ICT field and focuses on the best practices of innovative technologies in the fields of science and technology fight against epidemics, recovery of work, and promotion of digital economic development and cooperation." - }, - { - "title": "4G/5G FWA, New Engine for Revenue Growth", - "type": "Health", - "imgUrl": "/common/images/news_image13.jpg", - "reads": "445", - "likes": "872", - "content": "The reason why FWA is growing so fast is that it provides new opportunities for carriers in the consumer market. For example, a Philippine operator used 4G FWA to rapidly develop home broadband users. According to its third quarter financial report, the operator has successfully developed 2.78 million new users this year, accounting for 80% of the total broadband users. The percentage of broadband revenue increased from 12.3% in 2017 to 17.9%. With the development of wireless technologies, 5G FWA can provide gigabit home access experience similar to that of optical fibers, meeting services such as 4K/8K HD video and AR/VR interactive experience." - }, - { - "title": "Down! CPI released in November! These things are cheap", - "type": "Finance", - "imgUrl": "/common/images/news_image14.jpg", - "reads": "734", - "likes": "8788", - "content": "Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap." - }, - { - "title": "Comedy movie \"Big Red Envelope\" is set to celebrate the New Year", - "type": "Technology", - "imgUrl": "/common/images/news_image15.jpg", - "reads": "1010", - "likes": "3534", - "content": "Comedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New Year" - }, - { - "title": "Three living things are smart", - "type": "Sport", - "imgUrl": "/common/images/news_image16.jpg", - "reads": "1243", - "likes": "9141", - "content": "Lifan said at the press conference: \"Retrospective on the journey, we have always adhered to the spirit of initiative, innovation and science. Build core capabilities in terms of networks, technologies, and platforms, and deliver excellent services, technologies, and quality. Internal maintenance, optimization, and sharing are in place. Carriers, equipment vendors, and partners are working together to build an end-to-end network capability and win-win ecosystem to provide users with the best 5G experience and services.\"" - }, - { - "title": "Maximizing the Value of Wireless Networks and Ushering in the Golden Decade of 5G", - "type": "Internet", - "imgUrl": "/common/images/news_image17.jpg", - "reads": "7574", - "likes": "1439", - "content": "The 5G industry is developing faster than the previous standards. Currently, there are more than 100 5G commercial networks around the world, and the price of entry-level 5G mobile phones has fallen to CNY1,000, which has led to the rapid growth of 5G users worldwide. Thanks to this, leading operators have enjoyed the data dividend brought by 5G. The multi-dimensional package design and 5G message and 5G new communication services are upgraded to increase the ARPU of 5G users to different degrees.\nTo promote the further development of 5G networks and encourage more users to choose and prefer 5G networks, operators need to build 5G top-quality networks for individual users to achieve full-scenario coverage in densely populated urban areas, suburban areas, and indoor areas, allowing mobile phone users to access 5G services anytime, anywhere. In addition, 5G connection experience is optimized to ensure consistent user experience." - }, - { - "title": "Technology Helps Art, Leads a New Era", - "type": "Game", - "imgUrl": "/common/images/news_image18.jpg", - "reads": "6311", - "likes": "7114", - "content": "Zhang Wenlin spoke highly of the \"Dance Storm\". He believes that since the second season's premiere, the show has brought the contestants' exquisite dance moves, the wonderful host of Mr Ho Kung, the excellent comments of the judges' tutors, and the exquisite design of the staff to the audience, dedicate a beautiful visual feast! To help achieve fantastic visual effects, Hunan Radio and TV set up a joint team with Huawei to develop a spatio-temporal condensation system for Dance Storm 2. The system supports AI algorithms such as intelligent fast focusing, butterfly shooting, zoom-in, and multi-focus, with the help of the video 3.0+ platform of device-cloud synergy, the program team has made several industry-leading achievements, such as the three-dimensional storm moment with fantastic visual changes, free-view Dance Storm program with interactive control and rotation, and dance Storm with 360-degree panoramic view. VR programs." - }, - { - "title": "Open Intelligent Twin Ecosystem Is the Key to All-Scenario Intelligence", - "type": "Health", - "imgUrl": "/common/images/news_image19.jpg", - "reads": "6341", - "likes": "7164", - "content": "Intelligent upgrade will build core competitiveness in various industries. Huawei works with partners to integrate 5G, cloud, AI, intelligent edge, and industry applications to form an integrated intelligent system and create industry-leading smart experience. In the transportation industry, the abolition of highway toll stations at the provincial boundary enables fast and insensitive traffic, greatly improving traffic efficiency and reducing logistics transportation costs. Intelligent cameras are deployed on highway portals to collect vehicle traffic data 24 hours a day and send the data to the cloud in real time over the high-speed network for real-time charging. In addition, AI models trained on the cloud can be pushed to the edge so that cameras can have capabilities such as license plate recognition and vehicle feature extraction, and the capabilities can be continuously evolved. For example, in extreme weather conditions such as rain and snow, one-click upgrade can be performed on the cloud." - } -] - - - - -export default { - data() { - return { - titleList: titles, - newsList: newsData - } - }, - onInit() { - console.log("onInit::" + titles) - }, - changeNewsType: function (e) { - var type = titles[e.index].name; - this.newsList = []; - if (type === "All") { - this.newsList = newsData; - } else { - var newsArray = []; - for (var news of newsData) { - if (news.type === type) { - newsArray.push(news); - } - } - this.newsList = newsArray; - } - }, - startAbilityContinuation(news) { - // this.$element('continueAbilityDialog').close(); - - // console.info('featureAbility.startAbility deviceId=' + deviceId - // + ' deviceName=' + deviceName); - var params; - params = { - title: news.title, - type: news.type, - imgUrl: news.imgUrl, - reads: news.reads, - likes: news.likes, - content: news.content, - }; - var wantValue = { - bundleName: 'com.example.newsclientopenharmony', - abilityName: 'com.example.newsclientopenharmony.MainAbility2', - deviceId: '', - parameters: params - // //params: { - // "title": news.title, - // "type": news.type, - // "imgUrl": news.imgUrl, - // "reads": news.reads, - // "likes": news.likes, - // "content": news.content, - // //} - }; - - featureAbility.startAbility({ - want: wantValue - }).then((data) => { - console.info('featureAbility.startAbility finished, ' + JSON.stringify(data)); - }); - console.info('featureAbility.startAbility want=' + JSON.stringify(wantValue)); - console.info('featureAbility.startAbility end'); - }, - - // itemClick(news) { - // router.push({ - // uri: "MainAbility2/pages/index/index", - // params: { - // "title": news.title, - // "type": news.type, - // "imgUrl": news.imgUrl, - // "reads": news.reads, - // "likes": news.likes, - // "content": news.content, - // } - // }); - // - // } -} diff --git a/Distributed/NewsDemo/entry/.preview/merge_js_src/wearable/default/pages/index/index.js b/Distributed/NewsDemo/entry/.preview/merge_js_src/wearable/default/pages/index/index.js deleted file mode 100644 index 4a9d8d96cdc0c51dedc0d6d5f530c7b2a8716a0d..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/.preview/merge_js_src/wearable/default/pages/index/index.js +++ /dev/null @@ -1,264 +0,0 @@ -//import {titles, newsData} from '../../../MainAbility/common/data/data.js'; - -import featureAbility from '@ohos.ability.featureAbility'; - - const titles= [ - { - "name": "All" - }, - { - "name": "Health" - }, - { - "name": "Finance" - }, - { - "name": "Technology" - }, - { - "name": "Sport" - }, - { - "name": "Internet" - }, - { - "name": "Game" - } -] - - const newsData = [ - { - "title": "Best Enterprise Wi-Fi Network Award of the Wireless Broadband Alliance 2020", - "type": "Health", - "imgUrl": "/common/images/news_image1.jpg", - "reads": "54", - "likes": "81", - "content": "Recently, at the Wireless Broadband Alliance (WBA), an international industry organization, Huawei's AirEngine Wi-Fi 6 Solution Helps Factory Digital Transformation WBA 2020 Wi-Fi Industry Best Enterprise Wi-Fi Network Award. This is the first time that a Chinese Wi-Fi 6 vendor has won this award, which reflects the full recognition of Huawei AirEngine Wi-Fi 6 by global enterprise users." - }, - { - "title": "Latest technology and industry weather vane", - "type": "Health", - "imgUrl": "/common/images/news_image2.jpg", - "reads": "100", - "likes": "354", - "content": "With the large-scale commercial use of new technologies such as 5G, IoT, cloud computing, and AI, industry digital transformation has entered deep water. In addition, the sudden epidemic and carbon-neutral targets accelerate the transformation of society towards intelligence. When energy technologies are combined with power electronics and digital technologies, what direction will site energy develop?" - }, - { - "title": "Openness and Cooperation Facilitate Industry Upgrade", - "type": "Finance", - "imgUrl": "/common/images/news_image3.jpg", - "reads": "74", - "likes": "91", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." - }, - { - "title": "High-voltage super-fast charging is an inevitable trend", - "type": "Finance", - "imgUrl": "/common/images/news_image4.jpg", - "reads": "44", - "likes": "82", - "content": "Consumers have a lot of doubts about buying electric cars, compared to fuel cars. Wang Chao pointed out that among the factors affecting the purchase of electric vehicles, charging problems account for 80 percent, with a small number of charging piles (currently, the ratio of piles is 3.2:1) and a long charging time being the first to bear the brunt. As a result, many players in the charging infrastructure sector are looking for a break. To alleviate consumers' pain points of poor charging experience, we need to improve the pile ratio and shorten the charging time to meet consumers' requirements for fast charging." - }, - { - "title": "Huawei Releases the New Trend of Modular Power Supply, Facilitating Industry Upgrade Through Open Cooperation", - "type": "Technology", - "imgUrl": "/common/images/news_image5.jpg", - "reads": "73", - "likes": "888", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh. There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." - }, - { - "title": "Ten Future Trends of Digital Energy", - "type": "Technology", - "imgUrl": "/common/images/news_image6.jpg", - "reads": "100", - "likes": "354", - "content": "Energy digitalization is an inevitable trend. Innovative integration of digital and energy technologies enables end-to-end visual, manageable, and controllable intelligent management of energy infrastructure, improving energy efficiency.\nGreen power will benefit thousands of industries and households in the future. Green power, represented by PV, will become the main energy source. The era of price-effective PV is coming, and the integration of distributed power generation and solar storage will become an inevitable trend. Green Power will also help the ICT industry reduce its carbon footprint. In the future, we will build a \"zero-carbon network\" and \"zero-carbon\" data center. In addition, Huawei proposed the trend of full-link efficiency for the first time and implemented global optimization in terms of architecture and system." - }, - { - "title": "Ascend Helps Industry, Learning, and Research Promote AI Industry Development in the National AI Contest", - "type": "Sport", - "imgUrl": "/common/images/news_image7.jpg", - "reads": "123", - "likes": "911", - "content": "The holding of the National AI Contest further fulfilled the requirements of the Ministry of Science and Technology and the Ministry of Industry and Information Technology for Shenzhen to build the national new-generation AI innovation and development trial zone and the AI innovation and application pilot zone. It also promoted the integration and development of innovation elements such as industry, academia, capital, and talent, create an AI innovation atmosphere. Huawei has co-hosted two National AI Competitions in a row, aiming to promote technological progress, industrial upgrade, economic transformation, and social progress, and jointly promote the implementation of AI technologies. This is the most practical point for Huawei and the National AI Competition." - }, - { - "title": "Enterprise data centers are moving towards autonomous driving network", - "type": "Sport", - "imgUrl": "/common/images/news_image8.jpg", - "reads": "754", - "likes": "149", - "content": "More than 90% of enterprises say that fully autonomous driving data center network is their goal to achieve business agility, flexibility, and cost-effectiveness. This is a key research result in the data center network Autonomous Driving Index Report released by Huawei and IDC. Autonomous driving data center network helps enterprises restructure network architectures and operation models and enhance business resilience and continuity. In addition, regardless of the current level of data center network automation, IDC offers some guidance on how enterprises can move forward and move towards full automation." - }, - { - "title": "One optical fiber lights up a green smart room", - "type": "Internet", - "imgUrl": "/common/images/news_image9.jpg", - "reads": "631", - "likes": "714", - "content": "At the 2020 China Real Estate Development Summit held in Guangzhou, Jin Yuzhi, President of Huawei's Transmission and Access Product Line, delivered a keynote speech entitled \"One Fiber Lights Green Smart Rooms\" to discuss the convergence development trend of optical networks and real estate industries, proposes that optical fibers are the standard configuration of F5G smart real estate, and shares seven reasons for choosing Fiber to the Room (FTTR) all-optical home networking, we call on industry partners to work together to build an F5G real gigabit all-optical room ecosystem." - }, - { - "title": "BWS2020: Accelerate Network Autonomy and Enable Agile Business", - "type": "Internet", - "imgUrl": "/common/images/news_image10.jpg", - "reads": "53", - "likes": "824", - "content": "Currently, millions of enterprises embrace changes and accelerate their cloudification. SaaS traffic surges. Enterprise cloudification and multi-cloud collaboration become the new focus of cloud-network synergy . To address this challenge, Guo Dazheng, president of Huawei's data communications field, said: \"In cloud-network scenarios, iMaster NCE implements network as a service to help carriers provide cloud-network integration services and meet enterprise cloud access requirements.\" In 5G transport scenarios, improve the automation capability of the entire process of planning, construction, maintenance, and optimization to meet the requirements of large-scale 5G network construction and cloud network cost reduction and efficiency improvement." - }, - { - "title": "Trust technology, embrace openness, and share the world prosperity brought by technology", - "type": "Game", - "imgUrl": "/common/images/news_image11.jpg", - "reads": "1500", - "likes": "3542", - "content": "Huawei successfully held the TrustInTech 2020 online summit today. Ryan Ding, Executive Director of Huawei, President of the Carrier BG, and Jim Rogers, a senior Wall Street investor, GSMA Chief Marketing Officer Stephanie Lynch-Habib and other ICT industry experts and economists from around the world attended the summit. The summit pointed out that ICT has become a digital foundation for economic development and people's livelihood. In an era of accelerated commercial use of 5G, the world needs to embrace openness and cooperation to eliminate unnecessary resistance and fears about new technologies and transnational cooperation, thereby sharing the world prosperity brought by technology." - }, - { - "title": "Intelligent Twins Won the Leading Technology Achievement Award at the 7th World Internet Conference", - "type": "Game", - "imgUrl": "/common/images/news_image12.jpg", - "reads": "7451", - "likes": "9511", - "content": "Today, the Leading Technology Award was unveiled at the 7th World Internet Conference. As the industry's first systematic technical reference architecture for government and enterprise intelligence upgrade, intelligent virtual appliances have been recognized by experts and judges and won the Leading Scientific Achievement Award for their exploration and practice in various industries. This is the fifth time Huawei has won this award since 2016. The World Internet Leading Science and Technology Award showcases the latest technologies in the global ICT field and focuses on the best practices of innovative technologies in the fields of science and technology fight against epidemics, recovery of work, and promotion of digital economic development and cooperation." - }, - { - "title": "4G/5G FWA, New Engine for Revenue Growth", - "type": "Health", - "imgUrl": "/common/images/news_image13.jpg", - "reads": "445", - "likes": "872", - "content": "The reason why FWA is growing so fast is that it provides new opportunities for carriers in the consumer market. For example, a Philippine operator used 4G FWA to rapidly develop home broadband users. According to its third quarter financial report, the operator has successfully developed 2.78 million new users this year, accounting for 80% of the total broadband users. The percentage of broadband revenue increased from 12.3% in 2017 to 17.9%. With the development of wireless technologies, 5G FWA can provide gigabit home access experience similar to that of optical fibers, meeting services such as 4K/8K HD video and AR/VR interactive experience." - }, - { - "title": "Down! CPI released in November! These things are cheap", - "type": "Finance", - "imgUrl": "/common/images/news_image14.jpg", - "reads": "734", - "likes": "8788", - "content": "Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap." - }, - { - "title": "Comedy movie \"Big Red Envelope\" is set to celebrate the New Year", - "type": "Technology", - "imgUrl": "/common/images/news_image15.jpg", - "reads": "1010", - "likes": "3534", - "content": "Comedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New Year" - }, - { - "title": "Three living things are smart", - "type": "Sport", - "imgUrl": "/common/images/news_image16.jpg", - "reads": "1243", - "likes": "9141", - "content": "Lifan said at the press conference: \"Retrospective on the journey, we have always adhered to the spirit of initiative, innovation and science. Build core capabilities in terms of networks, technologies, and platforms, and deliver excellent services, technologies, and quality. Internal maintenance, optimization, and sharing are in place. Carriers, equipment vendors, and partners are working together to build an end-to-end network capability and win-win ecosystem to provide users with the best 5G experience and services.\"" - }, - { - "title": "Maximizing the Value of Wireless Networks and Ushering in the Golden Decade of 5G", - "type": "Internet", - "imgUrl": "/common/images/news_image17.jpg", - "reads": "7574", - "likes": "1439", - "content": "The 5G industry is developing faster than the previous standards. Currently, there are more than 100 5G commercial networks around the world, and the price of entry-level 5G mobile phones has fallen to CNY1,000, which has led to the rapid growth of 5G users worldwide. Thanks to this, leading operators have enjoyed the data dividend brought by 5G. The multi-dimensional package design and 5G message and 5G new communication services are upgraded to increase the ARPU of 5G users to different degrees.\nTo promote the further development of 5G networks and encourage more users to choose and prefer 5G networks, operators need to build 5G top-quality networks for individual users to achieve full-scenario coverage in densely populated urban areas, suburban areas, and indoor areas, allowing mobile phone users to access 5G services anytime, anywhere. In addition, 5G connection experience is optimized to ensure consistent user experience." - }, - { - "title": "Technology Helps Art, Leads a New Era", - "type": "Game", - "imgUrl": "/common/images/news_image18.jpg", - "reads": "6311", - "likes": "7114", - "content": "Zhang Wenlin spoke highly of the \"Dance Storm\". He believes that since the second season's premiere, the show has brought the contestants' exquisite dance moves, the wonderful host of Mr Ho Kung, the excellent comments of the judges' tutors, and the exquisite design of the staff to the audience, dedicate a beautiful visual feast! To help achieve fantastic visual effects, Hunan Radio and TV set up a joint team with Huawei to develop a spatio-temporal condensation system for Dance Storm 2. The system supports AI algorithms such as intelligent fast focusing, butterfly shooting, zoom-in, and multi-focus, with the help of the video 3.0+ platform of device-cloud synergy, the program team has made several industry-leading achievements, such as the three-dimensional storm moment with fantastic visual changes, free-view Dance Storm program with interactive control and rotation, and dance Storm with 360-degree panoramic view. VR programs." - }, - { - "title": "Open Intelligent Twin Ecosystem Is the Key to All-Scenario Intelligence", - "type": "Health", - "imgUrl": "/common/images/news_image19.jpg", - "reads": "6341", - "likes": "7164", - "content": "Intelligent upgrade will build core competitiveness in various industries. Huawei works with partners to integrate 5G, cloud, AI, intelligent edge, and industry applications to form an integrated intelligent system and create industry-leading smart experience. In the transportation industry, the abolition of highway toll stations at the provincial boundary enables fast and insensitive traffic, greatly improving traffic efficiency and reducing logistics transportation costs. Intelligent cameras are deployed on highway portals to collect vehicle traffic data 24 hours a day and send the data to the cloud in real time over the high-speed network for real-time charging. In addition, AI models trained on the cloud can be pushed to the edge so that cameras can have capabilities such as license plate recognition and vehicle feature extraction, and the capabilities can be continuously evolved. For example, in extreme weather conditions such as rain and snow, one-click upgrade can be performed on the cloud." - } -] - - - - -export default { - data() { - return { - titleList: titles, - newsList: newsData - } - }, - onInit() { - console.log("onInit::" + titles) - }, - changeNewsType: function (e) { - var type = titles[e.index].name; - this.newsList = []; - if (type === "All") { - this.newsList = newsData; - } else { - var newsArray = []; - for (var news of newsData) { - if (news.type === type) { - newsArray.push(news); - } - } - this.newsList = newsArray; - } - }, - startAbilityContinuation(news) { - // this.$element('continueAbilityDialog').close(); - - // console.info('featureAbility.startAbility deviceId=' + deviceId - // + ' deviceName=' + deviceName); - var params; - params = { - title: news.title, - type: news.type, - imgUrl: news.imgUrl, - reads: news.reads, - likes: news.likes, - content: news.content, - }; - var wantValue = { - bundleName: 'com.example.newsclientopenharmony', - abilityName: 'com.example.newsclientopenharmony.MainAbility2', - deviceId: '', - parameters: params - // //params: { - // "title": news.title, - // "type": news.type, - // "imgUrl": news.imgUrl, - // "reads": news.reads, - // "likes": news.likes, - // "content": news.content, - // //} - }; - - featureAbility.startAbility({ - want: wantValue - }).then((data) => { - console.info('featureAbility.startAbility finished, ' + JSON.stringify(data)); - }); - console.info('featureAbility.startAbility want=' + JSON.stringify(wantValue)); - console.info('featureAbility.startAbility end'); - }, - - // itemClick(news) { - // router.push({ - // uri: "MainAbility2/pages/index/index", - // params: { - // "title": news.title, - // "type": news.type, - // "imgUrl": news.imgUrl, - // "reads": news.reads, - // "likes": news.likes, - // "content": news.content, - // } - // }); - // - // } -} diff --git a/Distributed/NewsDemo/entry/src/main/config.json b/Distributed/NewsDemo/entry/src/main/config.json index d3ed04fb3427352b7c7938ee91f6389a1ab2190e..9821fe1a32651f101ae72ebe3ac6f4ad0c35e384 100644 --- a/Distributed/NewsDemo/entry/src/main/config.json +++ b/Distributed/NewsDemo/entry/src/main/config.json @@ -41,20 +41,7 @@ "icon": "$media:icon", "description": "$string:mainability_description", "formsEnabled": false, - "label": "$string:entry_MainAbility", - "type": "page", - "launchType": "standard" - }, - { - "orientation": "unspecified", - "visible": true, - "srcPath": "MainAbility2", - "name": ".MainAbility2", - "srcLanguage": "js", - "icon": "$media:icon", - "description": "$string:mainability2_description", - "formsEnabled": false, - "label": "$string:entry_MainAbility", + "label": "$string:NewsClient", "type": "page", "launchType": "standard" } @@ -62,23 +49,14 @@ "js": [ { "pages": [ - "pages/index/index" + "pages/index/index", + "pages/detail/detail" ], "name": ".MainAbility", "window": { "designWidth": 720, "autoDesignWidth": false } - }, - { - "pages": [ - "pages/index/index" - ], - "name": ".MainAbility2", - "window": { - "designWidth": 720, - "autoDesignWidth": false - } } ] } diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility/app.js b/Distributed/NewsDemo/entry/src/main/js/MainAbility/app.js index 6d060ffe5682c19fc83e2274a9e62cbc40a655f8..0f1892c02dda471104a94d8f12105df9aa34b558 100644 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility/app.js +++ b/Distributed/NewsDemo/entry/src/main/js/MainAbility/app.js @@ -1,8 +1,8 @@ export default { - onCreate() { - console.info("Application onCreate"); - }, - onDestroy() { - console.info("Application onDestroy"); - } + onCreate() { + console.info("Application onCreate"); + }, + onDestroy() { + console.info("Application onDestroy"); + } }; diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility/common/data/data.js b/Distributed/NewsDemo/entry/src/main/js/MainAbility/common/data/data.js deleted file mode 100644 index f76137341d300fd7566c565a5190f2f7ed39d4ab..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility/common/data/data.js +++ /dev/null @@ -1,184 +0,0 @@ - -const titles= [ - { - "name": "All" - }, - { - "name": "Health" - }, - { - "name": "Finance" - }, - { - "name": "Technology" - }, - { - "name": "Sport" - }, - { - "name": "Internet" - }, - { - "name": "Game" - } -] - -const newsData = [ - { - "title": "Best Enterprise Wi-Fi Network Award of the Wireless Broadband Alliance 2020", - "type": "Health", - "imgUrl": "/common/images/news_image1.jpg", - "reads": "54", - "likes": "81", - "content": "Recently, at the Wireless Broadband Alliance (WBA), an international industry organization, Huawei's AirEngine Wi-Fi 6 Solution Helps Factory Digital Transformation WBA 2020 Wi-Fi Industry Best Enterprise Wi-Fi Network Award. This is the first time that a Chinese Wi-Fi 6 vendor has won this award, which reflects the full recognition of Huawei AirEngine Wi-Fi 6 by global enterprise users." - }, - { - "title": "Latest technology and industry weather vane", - "type": "Health", - "imgUrl": "/common/images/news_image2.jpg", - "reads": "100", - "likes": "354", - "content": "With the large-scale commercial use of new technologies such as 5G, IoT, cloud computing, and AI, industry digital transformation has entered deep water. In addition, the sudden epidemic and carbon-neutral targets accelerate the transformation of society towards intelligence. When energy technologies are combined with power electronics and digital technologies, what direction will site energy develop?" - }, - { - "title": "Openness and Cooperation Facilitate Industry Upgrade", - "type": "Finance", - "imgUrl": "/common/images/news_image3.jpg", - "reads": "74", - "likes": "91", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." - }, - { - "title": "High-voltage super-fast charging is an inevitable trend", - "type": "Finance", - "imgUrl": "/common/images/news_image4.jpg", - "reads": "44", - "likes": "82", - "content": "Consumers have a lot of doubts about buying electric cars, compared to fuel cars. Wang Chao pointed out that among the factors affecting the purchase of electric vehicles, charging problems account for 80 percent, with a small number of charging piles (currently, the ratio of piles is 3.2:1) and a long charging time being the first to bear the brunt. As a result, many players in the charging infrastructure sector are looking for a break. To alleviate consumers' pain points of poor charging experience, we need to improve the pile ratio and shorten the charging time to meet consumers' requirements for fast charging." - }, - { - "title": "Huawei Releases the New Trend of Modular Power Supply, Facilitating Industry Upgrade Through Open Cooperation", - "type": "Technology", - "imgUrl": "/common/images/news_image5.jpg", - "reads": "73", - "likes": "888", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh. There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." - }, - { - "title": "Ten Future Trends of Digital Energy", - "type": "Technology", - "imgUrl": "/common/images/news_image6.jpg", - "reads": "100", - "likes": "354", - "content": "Energy digitalization is an inevitable trend. Innovative integration of digital and energy technologies enables end-to-end visual, manageable, and controllable intelligent management of energy infrastructure, improving energy efficiency.\nGreen power will benefit thousands of industries and households in the future. Green power, represented by PV, will become the main energy source. The era of price-effective PV is coming, and the integration of distributed power generation and solar storage will become an inevitable trend. Green Power will also help the ICT industry reduce its carbon footprint. In the future, we will build a \"zero-carbon network\" and \"zero-carbon\" data center. In addition, Huawei proposed the trend of full-link efficiency for the first time and implemented global optimization in terms of architecture and system." - }, - { - "title": "Ascend Helps Industry, Learning, and Research Promote AI Industry Development in the National AI Contest", - "type": "Sport", - "imgUrl": "/common/images/news_image7.jpg", - "reads": "123", - "likes": "911", - "content": "The holding of the National AI Contest further fulfilled the requirements of the Ministry of Science and Technology and the Ministry of Industry and Information Technology for Shenzhen to build the national new-generation AI innovation and development trial zone and the AI innovation and application pilot zone. It also promoted the integration and development of innovation elements such as industry, academia, capital, and talent, create an AI innovation atmosphere. Huawei has co-hosted two National AI Competitions in a row, aiming to promote technological progress, industrial upgrade, economic transformation, and social progress, and jointly promote the implementation of AI technologies. This is the most practical point for Huawei and the National AI Competition." - }, - { - "title": "Enterprise data centers are moving towards autonomous driving network", - "type": "Sport", - "imgUrl": "/common/images/news_image8.jpg", - "reads": "754", - "likes": "149", - "content": "More than 90% of enterprises say that fully autonomous driving data center network is their goal to achieve business agility, flexibility, and cost-effectiveness. This is a key research result in the data center network Autonomous Driving Index Report released by Huawei and IDC. Autonomous driving data center network helps enterprises restructure network architectures and operation models and enhance business resilience and continuity. In addition, regardless of the current level of data center network automation, IDC offers some guidance on how enterprises can move forward and move towards full automation." - }, - { - "title": "One optical fiber lights up a green smart room", - "type": "Internet", - "imgUrl": "/common/images/news_image9.jpg", - "reads": "631", - "likes": "714", - "content": "At the 2020 China Real Estate Development Summit held in Guangzhou, Jin Yuzhi, President of Huawei's Transmission and Access Product Line, delivered a keynote speech entitled \"One Fiber Lights Green Smart Rooms\" to discuss the convergence development trend of optical networks and real estate industries, proposes that optical fibers are the standard configuration of F5G smart real estate, and shares seven reasons for choosing Fiber to the Room (FTTR) all-optical home networking, we call on industry partners to work together to build an F5G real gigabit all-optical room ecosystem." - }, - { - "title": "BWS2020: Accelerate Network Autonomy and Enable Agile Business", - "type": "Internet", - "imgUrl": "/common/images/news_image10.jpg", - "reads": "53", - "likes": "824", - "content": "Currently, millions of enterprises embrace changes and accelerate their cloudification. SaaS traffic surges. Enterprise cloudification and multi-cloud collaboration become the new focus of cloud-network synergy . To address this challenge, Guo Dazheng, president of Huawei's data communications field, said: \"In cloud-network scenarios, iMaster NCE implements network as a service to help carriers provide cloud-network integration services and meet enterprise cloud access requirements.\" In 5G transport scenarios, improve the automation capability of the entire process of planning, construction, maintenance, and optimization to meet the requirements of large-scale 5G network construction and cloud network cost reduction and efficiency improvement." - }, - { - "title": "Trust technology, embrace openness, and share the world prosperity brought by technology", - "type": "Game", - "imgUrl": "/common/images/news_image11.jpg", - "reads": "1500", - "likes": "3542", - "content": "Huawei successfully held the TrustInTech 2020 online summit today. Ryan Ding, Executive Director of Huawei, President of the Carrier BG, and Jim Rogers, a senior Wall Street investor, GSMA Chief Marketing Officer Stephanie Lynch-Habib and other ICT industry experts and economists from around the world attended the summit. The summit pointed out that ICT has become a digital foundation for economic development and people's livelihood. In an era of accelerated commercial use of 5G, the world needs to embrace openness and cooperation to eliminate unnecessary resistance and fears about new technologies and transnational cooperation, thereby sharing the world prosperity brought by technology." - }, - { - "title": "Intelligent Twins Won the Leading Technology Achievement Award at the 7th World Internet Conference", - "type": "Game", - "imgUrl": "/common/images/news_image12.jpg", - "reads": "7451", - "likes": "9511", - "content": "Today, the Leading Technology Award was unveiled at the 7th World Internet Conference. As the industry's first systematic technical reference architecture for government and enterprise intelligence upgrade, intelligent virtual appliances have been recognized by experts and judges and won the Leading Scientific Achievement Award for their exploration and practice in various industries. This is the fifth time Huawei has won this award since 2016. The World Internet Leading Science and Technology Award showcases the latest technologies in the global ICT field and focuses on the best practices of innovative technologies in the fields of science and technology fight against epidemics, recovery of work, and promotion of digital economic development and cooperation." - }, - { - "title": "4G/5G FWA, New Engine for Revenue Growth", - "type": "Health", - "imgUrl": "/common/images/news_image13.jpg", - "reads": "445", - "likes": "872", - "content": "The reason why FWA is growing so fast is that it provides new opportunities for carriers in the consumer market. For example, a Philippine operator used 4G FWA to rapidly develop home broadband users. According to its third quarter financial report, the operator has successfully developed 2.78 million new users this year, accounting for 80% of the total broadband users. The percentage of broadband revenue increased from 12.3% in 2017 to 17.9%. With the development of wireless technologies, 5G FWA can provide gigabit home access experience similar to that of optical fibers, meeting services such as 4K/8K HD video and AR/VR interactive experience." - }, - { - "title": "Down! CPI released in November! These things are cheap", - "type": "Finance", - "imgUrl": "/common/images/news_image14.jpg", - "reads": "734", - "likes": "8788", - "content": "Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap." - }, - { - "title": "Comedy movie \"Big Red Envelope\" is set to celebrate the New Year", - "type": "Technology", - "imgUrl": "/common/images/news_image15.jpg", - "reads": "1010", - "likes": "3534", - "content": "Comedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New Year" - }, - { - "title": "Three living things are smart", - "type": "Sport", - "imgUrl": "/common/images/news_image16.jpg", - "reads": "1243", - "likes": "9141", - "content": "Lifan said at the press conference: \"Retrospective on the journey, we have always adhered to the spirit of initiative, innovation and science. Build core capabilities in terms of networks, technologies, and platforms, and deliver excellent services, technologies, and quality. Internal maintenance, optimization, and sharing are in place. Carriers, equipment vendors, and partners are working together to build an end-to-end network capability and win-win ecosystem to provide users with the best 5G experience and services.\"" - }, - { - "title": "Maximizing the Value of Wireless Networks and Ushering in the Golden Decade of 5G", - "type": "Internet", - "imgUrl": "/common/images/news_image17.jpg", - "reads": "7574", - "likes": "1439", - "content": "The 5G industry is developing faster than the previous standards. Currently, there are more than 100 5G commercial networks around the world, and the price of entry-level 5G mobile phones has fallen to CNY1,000, which has led to the rapid growth of 5G users worldwide. Thanks to this, leading operators have enjoyed the data dividend brought by 5G. The multi-dimensional package design and 5G message and 5G new communication services are upgraded to increase the ARPU of 5G users to different degrees.\nTo promote the further development of 5G networks and encourage more users to choose and prefer 5G networks, operators need to build 5G top-quality networks for individual users to achieve full-scenario coverage in densely populated urban areas, suburban areas, and indoor areas, allowing mobile phone users to access 5G services anytime, anywhere. In addition, 5G connection experience is optimized to ensure consistent user experience." - }, - { - "title": "Technology Helps Art, Leads a New Era", - "type": "Game", - "imgUrl": "/common/images/news_image18.jpg", - "reads": "6311", - "likes": "7114", - "content": "Zhang Wenlin spoke highly of the \"Dance Storm\". He believes that since the second season's premiere, the show has brought the contestants' exquisite dance moves, the wonderful host of Mr Ho Kung, the excellent comments of the judges' tutors, and the exquisite design of the staff to the audience, dedicate a beautiful visual feast! To help achieve fantastic visual effects, Hunan Radio and TV set up a joint team with Huawei to develop a spatio-temporal condensation system for Dance Storm 2. The system supports AI algorithms such as intelligent fast focusing, butterfly shooting, zoom-in, and multi-focus, with the help of the video 3.0+ platform of device-cloud synergy, the program team has made several industry-leading achievements, such as the three-dimensional storm moment with fantastic visual changes, free-view Dance Storm program with interactive control and rotation, and dance Storm with 360-degree panoramic view. VR programs." - }, - { - "title": "Open Intelligent Twin Ecosystem Is the Key to All-Scenario Intelligence", - "type": "Health", - "imgUrl": "/common/images/news_image19.jpg", - "reads": "6341", - "likes": "7164", - "content": "Intelligent upgrade will build core competitiveness in various industries. Huawei works with partners to integrate 5G, cloud, AI, intelligent edge, and industry applications to form an integrated intelligent system and create industry-leading smart experience. In the transportation industry, the abolition of highway toll stations at the provincial boundary enables fast and insensitive traffic, greatly improving traffic efficiency and reducing logistics transportation costs. Intelligent cameras are deployed on highway portals to collect vehicle traffic data 24 hours a day and send the data to the cloud in real time over the high-speed network for real-time charging. In addition, AI models trained on the cloud can be pushed to the edge so that cameras can have capabilities such as license plate recognition and vehicle feature extraction, and the capabilities can be continuously evolved. For example, in extreme weather conditions such as rain and snow, one-click upgrade can be performed on the cloud." - } -] - -export {titles, newsData} - - - diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility/i18n/en-US.json b/Distributed/NewsDemo/entry/src/main/js/MainAbility/i18n/en-US.json index 547e7e13afae9b28f836a4d857e576413ea82bc5..02536fd164b9f0b11aab483ab81ed82ae4ae9c59 100644 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility/i18n/en-US.json +++ b/Distributed/NewsDemo/entry/src/main/js/MainAbility/i18n/en-US.json @@ -1,7 +1,7 @@ { "strings": { - "hello": "Hello", - "world": "World", + "hello": "shizhe", + "world": "Hello", "page": "Second Page", "next": "Next Page", "back": "Back", diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility/i18n/zh-CN.json b/Distributed/NewsDemo/entry/src/main/js/MainAbility/i18n/zh-CN.json index 38de361bd7bac39682ded8a4839f9cf7822fbdf0..d80a8bb61500ee734a54b5c4002f15ed38654308 100644 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility/i18n/zh-CN.json +++ b/Distributed/NewsDemo/entry/src/main/js/MainAbility/i18n/zh-CN.json @@ -1,6 +1,6 @@ { "strings": { - "hello": "您好", + "hello": "SHIZHE", "world": "世界", "page": "第二页", "next": "下一页", diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/pages/index/index.css b/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/detail/detail.css similarity index 95% rename from Distributed/NewsDemo/entry/src/main/js/MainAbility2/pages/index/index.css rename to Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/detail/detail.css index afa1298e53d0db8458cd7856a575e68417b3e4d7..f3e430a9b7a5c04340a29c85e7a34335b6311a64 100644 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/pages/index/index.css +++ b/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/detail/detail.css @@ -20,18 +20,25 @@ } .text-title { - margin: 20px; - font-size: 50px; + height: 200px; + word-break:normal; + max-lines:2; + text-overflow:ellipsis; + margin: 10px; + font-size: 45px; } .text-reads { + height: 60px; font-size: 32px; text-color: #666666; - margin: 20px; + margin: 10px; } .image { margin: 20px; + height: 450px; + object-fit: cover; } .text-content { @@ -293,4 +300,4 @@ @media screen and (device-type: phone) and (orientation: landscape) { -} +} \ No newline at end of file diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/pages/index/index.hml b/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/detail/detail.hml similarity index 56% rename from Distributed/NewsDemo/entry/src/main/js/MainAbility2/pages/index/index.hml rename to Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/detail/detail.hml index d0992c27de16cf83cc5163fe665c179a90149f50..604bc6ac332c034af73366ffb689bc99a7ce56e8 100644 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/pages/index/index.hml +++ b/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/detail/detail.hml @@ -14,9 +14,8 @@ limitations under the License. -->
- {{ title }} - reads:{{ reads }} likes:{{ likes }} + reads: {{ reads }} likes: {{ likes }} {{ content }} @@ -24,29 +23,28 @@ limitations under the License.
+ -
- - -
- 选择设备 - - - - + +
+ 选择设备 + + + {{ $item.deviceName }} + + + -
- +
+ 取消 + 确定
-
diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/detail/detail.js b/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/detail/detail.js new file mode 100644 index 0000000000000000000000000000000000000000..cbeacd777220988266f5d37de87ec1dff7585194 --- /dev/null +++ b/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/detail/detail.js @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021 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 router from '@system.router'; +import deviceManager from '@ohos.distributedHardware.deviceManager'; +import featureAbility from '@ohos.ability.featureAbility'; + +export default { + data: { + title: '', + type: '', + imgUrl: '', + reads: '', + likes: '', + content: '', + deviceList: [], + deviceMag: {} + }, + + onInit() { + if (router.getParams()) { + console.info('router.getParams():' + JSON.stringify(router.getParams())); + } else { + // 从远端获取数据 + featureAbility.getWant() + .then((want) => { + this.title = want.parameters.title; + this.imgUrl = want.parameters.imgUrl; + this.reads = want.parameters.reads; + this.likes = want.parameters.likes; + this.content = want.parameters.content; + console.info('featureAbility.getWant' + JSON.stringify(want)); + }).catch((error) => { + }); + } + }, + + toShare() { + // 创建设备管理实例 + deviceManager.createDeviceManager('com.huawei.newsdemooh', (err, data) => { + if (err) { + return; + } + this.deviceMag = data; + // 获取所有可信设备的列表 + this.deviceList = this.deviceMag.getTrustedDeviceListSync(); + }); + // 循环遍历设备列表,获取设备名称和设备Id + for (let i = 0; i < this.deviceList.length; i++) { + this.deviceList[i] = { + deviceName: this.deviceList[i].deviceName, + deviceId: this.deviceList[i].deviceId, + checked: false + }; + } + this.$element('showDialog').show(); + }, + + chooseCancel() { + this.$element('showDialog').close(); + }, + + chooseComform() { + this.$element('showDialog').close(); + for (let i = 0; i < this.deviceList.length; i++) { + // 判断设备是否被选中 + if (this.deviceList[i].checked) { + const params = { + url: 'pages/detail/detail', + title: this.title, + type: this.type, + imgUrl: this.imgUrl, + reads: this.reads, + likes: this.likes, + content: this.content + }; + + const wantValue = { + bundleName: 'com.huawei.newsdemooh', + abilityName: 'com.huawei.newsdemooh.MainAbility', + deviceId: this.deviceList[i].deviceId, + parameters: params + }; + + featureAbility.startAbility({ + want: wantValue + }).then((data) => { + console.info('featureAbility.startAbility finished, ' + JSON.stringify(data)); + }); + console.info('featureAbility.startAbility want=' + JSON.stringify(wantValue)); + console.info('featureAbility.startAbility end'); + } + } + }, + + selectDevice(index, e) { + this.deviceList[index].checked = e.checked; + }, + + onDestroy() { + this.deviceMag.release(); + } +}; diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.hml b/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.hml index ade9032307a08c4dea65526bc83ba53c6cec50d6..75c5dcf10ce66c2e64734a408f381e49df9e5898 100644 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.hml +++ b/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.hml @@ -22,7 +22,7 @@ limitations under the License.
- +
diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.js b/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.js index 5745b3df993cdda59a8dbcab1f5f11a640731c24..dc831ac472b7de476402d3b007bd988af3a1e0ab 100644 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.js +++ b/Distributed/NewsDemo/entry/src/main/js/MainAbility/pages/index/index.js @@ -13,236 +13,227 @@ * limitations under the License. */ -import featureAbility from '@ohos.ability.featureAbility'; +import router from '@system.router'; const titles = [ - { - "name": "All" - }, - { - "name": "Health" - }, - { - "name": "Finance" - }, - { - "name": "Technology" - }, - { - "name": "Sport" - }, - { - "name": "Internet" - }, - { - "name": "Game" - } -] + { + 'name': 'All' + }, + { + 'name': 'Health' + }, + { + 'name': 'Finance' + }, + { + 'name': 'Technology' + }, + { + 'name': 'Sport' + }, + { + 'name': 'Internet' + }, + { + 'name': 'Game' + } +]; const newsData = [ - { - "title": "Best Enterprise Wi-Fi Network Award of the Wireless Broadband Alliance 2020", - "type": "Health", - "imgUrl": "/common/images/news_image1.jpg", - "reads": "54", - "likes": "81", - "content": "Recently, at the Wireless Broadband Alliance (WBA), an international industry organization, Huawei's AirEngine Wi-Fi 6 Solution Helps Factory Digital Transformation WBA 2020 Wi-Fi Industry Best Enterprise Wi-Fi Network Award. This is the first time that a Chinese Wi-Fi 6 vendor has won this award, which reflects the full recognition of Huawei AirEngine Wi-Fi 6 by global enterprise users." - }, - { - "title": "Latest technology and industry weather vane", - "type": "Health", - "imgUrl": "/common/images/news_image2.jpg", - "reads": "100", - "likes": "354", - "content": "With the large-scale commercial use of new technologies such as 5G, IoT, cloud computing, and AI, industry digital transformation has entered deep water. In addition, the sudden epidemic and carbon-neutral targets accelerate the transformation of society towards intelligence. When energy technologies are combined with power electronics and digital technologies, what direction will site energy develop?" - }, - { - "title": "Openness and Cooperation Facilitate Industry Upgrade", - "type": "Finance", - "imgUrl": "/common/images/news_image3.jpg", - "reads": "74", - "likes": "91", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." - }, - { - "title": "High-voltage super-fast charging is an inevitable trend", - "type": "Finance", - "imgUrl": "/common/images/news_image4.jpg", - "reads": "44", - "likes": "82", - "content": "Consumers have a lot of doubts about buying electric cars, compared to fuel cars. Wang Chao pointed out that among the factors affecting the purchase of electric vehicles, charging problems account for 80 percent, with a small number of charging piles (currently, the ratio of piles is 3.2:1) and a long charging time being the first to bear the brunt. As a result, many players in the charging infrastructure sector are looking for a break. To alleviate consumers' pain points of poor charging experience, we need to improve the pile ratio and shorten the charging time to meet consumers' requirements for fast charging." - }, - { - "title": "Huawei Releases the New Trend of Modular Power Supply, Facilitating Industry Upgrade Through Open Cooperation", - "type": "Technology", - "imgUrl": "/common/images/news_image5.jpg", - "reads": "73", - "likes": "888", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh. There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." - }, - { - "title": "Ten Future Trends of Digital Energy", - "type": "Technology", - "imgUrl": "/common/images/news_image6.jpg", - "reads": "100", - "likes": "354", - "content": "Energy digitalization is an inevitable trend. Innovative integration of digital and energy technologies enables end-to-end visual, manageable, and controllable intelligent management of energy infrastructure, improving energy efficiency.\nGreen power will benefit thousands of industries and households in the future. Green power, represented by PV, will become the main energy source. The era of price-effective PV is coming, and the integration of distributed power generation and solar storage will become an inevitable trend. Green Power will also help the ICT industry reduce its carbon footprint. In the future, we will build a \"zero-carbon network\" and \"zero-carbon\" data center. In addition, Huawei proposed the trend of full-link efficiency for the first time and implemented global optimization in terms of architecture and system." - }, - { - "title": "Ascend Helps Industry, Learning, and Research Promote AI Industry Development in the National AI Contest", - "type": "Sport", - "imgUrl": "/common/images/news_image7.jpg", - "reads": "123", - "likes": "911", - "content": "The holding of the National AI Contest further fulfilled the requirements of the Ministry of Science and Technology and the Ministry of Industry and Information Technology for Shenzhen to build the national new-generation AI innovation and development trial zone and the AI innovation and application pilot zone. It also promoted the integration and development of innovation elements such as industry, academia, capital, and talent, create an AI innovation atmosphere. Huawei has co-hosted two National AI Competitions in a row, aiming to promote technological progress, industrial upgrade, economic transformation, and social progress, and jointly promote the implementation of AI technologies. This is the most practical point for Huawei and the National AI Competition." - }, - { - "title": "Enterprise data centers are moving towards autonomous driving network", - "type": "Sport", - "imgUrl": "/common/images/news_image8.jpg", - "reads": "754", - "likes": "149", - "content": "More than 90% of enterprises say that fully autonomous driving data center network is their goal to achieve business agility, flexibility, and cost-effectiveness. This is a key research result in the data center network Autonomous Driving Index Report released by Huawei and IDC. Autonomous driving data center network helps enterprises restructure network architectures and operation models and enhance business resilience and continuity. In addition, regardless of the current level of data center network automation, IDC offers some guidance on how enterprises can move forward and move towards full automation." - }, - { - "title": "One optical fiber lights up a green smart room", - "type": "Internet", - "imgUrl": "/common/images/news_image9.jpg", - "reads": "631", - "likes": "714", - "content": "At the 2020 China Real Estate Development Summit held in Guangzhou, Jin Yuzhi, President of Huawei's Transmission and Access Product Line, delivered a keynote speech entitled \"One Fiber Lights Green Smart Rooms\" to discuss the convergence development trend of optical networks and real estate industries, proposes that optical fibers are the standard configuration of F5G smart real estate, and shares seven reasons for choosing Fiber to the Room (FTTR) all-optical home networking, we call on industry partners to work together to build an F5G real gigabit all-optical room ecosystem." - }, - { - "title": "BWS2020: Accelerate Network Autonomy and Enable Agile Business", - "type": "Internet", - "imgUrl": "/common/images/news_image10.jpg", - "reads": "53", - "likes": "824", - "content": "Currently, millions of enterprises embrace changes and accelerate their cloudification. SaaS traffic surges. Enterprise cloudification and multi-cloud collaboration become the new focus of cloud-network synergy . To address this challenge, Guo Dazheng, president of Huawei's data communications field, said: \"In cloud-network scenarios, iMaster NCE implements network as a service to help carriers provide cloud-network integration services and meet enterprise cloud access requirements.\" In 5G transport scenarios, improve the automation capability of the entire process of planning, construction, maintenance, and optimization to meet the requirements of large-scale 5G network construction and cloud network cost reduction and efficiency improvement." - }, - { - "title": "Trust technology, embrace openness, and share the world prosperity brought by technology", - "type": "Game", - "imgUrl": "/common/images/news_image11.jpg", - "reads": "1500", - "likes": "3542", - "content": "Huawei successfully held the TrustInTech 2020 online summit today. Ryan Ding, Executive Director of Huawei, President of the Carrier BG, and Jim Rogers, a senior Wall Street investor, GSMA Chief Marketing Officer Stephanie Lynch-Habib and other ICT industry experts and economists from around the world attended the summit. The summit pointed out that ICT has become a digital foundation for economic development and people's livelihood. In an era of accelerated commercial use of 5G, the world needs to embrace openness and cooperation to eliminate unnecessary resistance and fears about new technologies and transnational cooperation, thereby sharing the world prosperity brought by technology." - }, - { - "title": "Intelligent Twins Won the Leading Technology Achievement Award at the 7th World Internet Conference", - "type": "Game", - "imgUrl": "/common/images/news_image12.jpg", - "reads": "7451", - "likes": "9511", - "content": "Today, the Leading Technology Award was unveiled at the 7th World Internet Conference. As the industry's first systematic technical reference architecture for government and enterprise intelligence upgrade, intelligent virtual appliances have been recognized by experts and judges and won the Leading Scientific Achievement Award for their exploration and practice in various industries. This is the fifth time Huawei has won this award since 2016. The World Internet Leading Science and Technology Award showcases the latest technologies in the global ICT field and focuses on the best practices of innovative technologies in the fields of science and technology fight against epidemics, recovery of work, and promotion of digital economic development and cooperation." - }, - { - "title": "4G/5G FWA, New Engine for Revenue Growth", - "type": "Health", - "imgUrl": "/common/images/news_image13.jpg", - "reads": "445", - "likes": "872", - "content": "The reason why FWA is growing so fast is that it provides new opportunities for carriers in the consumer market. For example, a Philippine operator used 4G FWA to rapidly develop home broadband users. According to its third quarter financial report, the operator has successfully developed 2.78 million new users this year, accounting for 80% of the total broadband users. The percentage of broadband revenue increased from 12.3% in 2017 to 17.9%. With the development of wireless technologies, 5G FWA can provide gigabit home access experience similar to that of optical fibers, meeting services such as 4K/8K HD video and AR/VR interactive experience." - }, - { - "title": "Down! CPI released in November! These things are cheap", - "type": "Finance", - "imgUrl": "/common/images/news_image14.jpg", - "reads": "734", - "likes": "8788", - "content": "Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap." - }, - { - "title": "Comedy movie \"Big Red Envelope\" is set to celebrate the New Year", - "type": "Technology", - "imgUrl": "/common/images/news_image15.jpg", - "reads": "1010", - "likes": "3534", - "content": "Comedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New Year" - }, - { - "title": "Three living things are smart", - "type": "Sport", - "imgUrl": "/common/images/news_image16.jpg", - "reads": "1243", - "likes": "9141", - "content": "Lifan said at the press conference: \"Retrospective on the journey, we have always adhered to the spirit of initiative, innovation and science. Build core capabilities in terms of networks, technologies, and platforms, and deliver excellent services, technologies, and quality. Internal maintenance, optimization, and sharing are in place. Carriers, equipment vendors, and partners are working together to build an end-to-end network capability and win-win ecosystem to provide users with the best 5G experience and services.\"" - }, - { - "title": "Maximizing the Value of Wireless Networks and Ushering in the Golden Decade of 5G", - "type": "Internet", - "imgUrl": "/common/images/news_image17.jpg", - "reads": "7574", - "likes": "1439", - "content": "The 5G industry is developing faster than the previous standards. Currently, there are more than 100 5G commercial networks around the world, and the price of entry-level 5G mobile phones has fallen to CNY1,000, which has led to the rapid growth of 5G users worldwide. Thanks to this, leading operators have enjoyed the data dividend brought by 5G. The multi-dimensional package design and 5G message and 5G new communication services are upgraded to increase the ARPU of 5G users to different degrees.\nTo promote the further development of 5G networks and encourage more users to choose and prefer 5G networks, operators need to build 5G top-quality networks for individual users to achieve full-scenario coverage in densely populated urban areas, suburban areas, and indoor areas, allowing mobile phone users to access 5G services anytime, anywhere. In addition, 5G connection experience is optimized to ensure consistent user experience." - }, - { - "title": "Technology Helps Art, Leads a New Era", - "type": "Game", - "imgUrl": "/common/images/news_image18.jpg", - "reads": "6311", - "likes": "7114", - "content": "Zhang Wenlin spoke highly of the \"Dance Storm\". He believes that since the second season's premiere, the show has brought the contestants' exquisite dance moves, the wonderful host of Mr Ho Kung, the excellent comments of the judges' tutors, and the exquisite design of the staff to the audience, dedicate a beautiful visual feast! To help achieve fantastic visual effects, Hunan Radio and TV set up a joint team with Huawei to develop a spatio-temporal condensation system for Dance Storm 2. The system supports AI algorithms such as intelligent fast focusing, butterfly shooting, zoom-in, and multi-focus, with the help of the video 3.0+ platform of device-cloud synergy, the program team has made several industry-leading achievements, such as the three-dimensional storm moment with fantastic visual changes, free-view Dance Storm program with interactive control and rotation, and dance Storm with 360-degree panoramic view. VR programs." - }, - { - "title": "Open Intelligent Twin Ecosystem Is the Key to All-Scenario Intelligence", - "type": "Health", - "imgUrl": "/common/images/news_image19.jpg", - "reads": "6341", - "likes": "7164", - "content": "Intelligent upgrade will build core competitiveness in various industries. Huawei works with partners to integrate 5G, cloud, AI, intelligent edge, and industry applications to form an integrated intelligent system and create industry-leading smart experience. In the transportation industry, the abolition of highway toll stations at the provincial boundary enables fast and insensitive traffic, greatly improving traffic efficiency and reducing logistics transportation costs. Intelligent cameras are deployed on highway portals to collect vehicle traffic data 24 hours a day and send the data to the cloud in real time over the high-speed network for real-time charging. In addition, AI models trained on the cloud can be pushed to the edge so that cameras can have capabilities such as license plate recognition and vehicle feature extraction, and the capabilities can be continuously evolved. For example, in extreme weather conditions such as rain and snow, one-click upgrade can be performed on the cloud." - } -] - + { + 'title': 'Best Enterprise Wi-Fi Network Award of the Wireless Broadband Alliance 2020', + 'type': 'Health', + 'imgUrl': '/common/images/news_image1.jpg', + 'reads': '54', + 'likes': '81', + 'content': "Recently, at the Wireless Broadband Alliance (WBA), an international industry organization, Huawei's AirEngine Wi-Fi 6 Solution Helps Factory Digital Transformation WBA 2020 Wi-Fi Industry Best Enterprise Wi-Fi Network Award. This is the first time that a Chinese Wi-Fi 6 vendor has won this award, which reflects the full recognition of Huawei AirEngine Wi-Fi 6 by global enterprise users." + }, + { + 'title': 'Latest technology and industry weather vane', + 'type': 'Health', + 'imgUrl': '/common/images/news_image2.jpg', + 'reads': '100', + 'likes': '354', + 'content': 'With the large-scale commercial use of new technologies such as 5G, IoT, cloud computing, and AI, industry digital transformation has entered deep water. In addition, the sudden epidemic and carbon-neutral targets accelerate the transformation of society towards intelligence. When energy technologies are combined with power electronics and digital technologies, what direction will site energy develop?' + }, + { + 'title': 'Openness and Cooperation Facilitate Industry Upgrade', + 'type': 'Finance', + 'imgUrl': '/common/images/news_image3.jpg', + 'reads': '74', + 'likes': '91', + 'content': 'Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life.' + }, + { + 'title': 'High-voltage super-fast charging is an inevitable trend', + 'type': 'Finance', + 'imgUrl': '/common/images/news_image4.jpg', + 'reads': '44', + 'likes': '82', + 'content': "Consumers have a lot of doubts about buying electric cars, compared to fuel cars. Wang Chao pointed out that among the factors affecting the purchase of electric vehicles, charging problems account for 80 percent, with a small number of charging piles (currently, the ratio of piles is 3.2:1) and a long charging time being the first to bear the brunt. As a result, many players in the charging infrastructure sector are looking for a break. To alleviate consumers' pain points of poor charging experience, we need to improve the pile ratio and shorten the charging time to meet consumers' requirements for fast charging." + }, + { + 'title': 'Huawei Releases the New Trend of Modular Power Supply, Facilitating Industry Upgrade Through Open Cooperation', + 'type': 'Technology', + 'imgUrl': '/common/images/news_image5.jpg', + 'reads': '73', + 'likes': '888', + 'content': 'Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh. There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life.' + }, + { + 'title': 'Ten Future Trends of Digital Energy', + 'type': 'Technology', + 'imgUrl': '/common/images/news_image6.jpg', + 'reads': '100', + 'likes': '354', + 'content': 'Energy digitalization is an inevitable trend. Innovative integration of digital and energy technologies enables end-to-end visual, manageable, and controllable intelligent management of energy infrastructure, improving energy efficiency.\nGreen power will benefit thousands of industries and households in the future. Green power, represented by PV, will become the main energy source. The era of price-effective PV is coming, and the integration of distributed power generation and solar storage will become an inevitable trend. Green Power will also help the ICT industry reduce its carbon footprint. In the future, we will build a "zero-carbon network" and "zero-carbon" data center. In addition, Huawei proposed the trend of full-link efficiency for the first time and implemented global optimization in terms of architecture and system.' + }, + { + 'title': 'Ascend Helps Industry, Learning, and Research Promote AI Industry Development in the National AI Contest', + 'type': 'Sport', + 'imgUrl': '/common/images/news_image7.jpg', + 'reads': '123', + 'likes': '911', + 'content': 'The holding of the National AI Contest further fulfilled the requirements of the Ministry of Science and Technology and the Ministry of Industry and Information Technology for Shenzhen to build the national new-generation AI innovation and development trial zone and the AI innovation and application pilot zone. It also promoted the integration and development of innovation elements such as industry, academia, capital, and talent, create an AI innovation atmosphere. Huawei has co-hosted two National AI Competitions in a row, aiming to promote technological progress, industrial upgrade, economic transformation, and social progress, and jointly promote the implementation of AI technologies. This is the most practical point for Huawei and the National AI Competition.' + }, + { + 'title': 'Enterprise data centers are moving towards autonomous driving network', + 'type': 'Sport', + 'imgUrl': '/common/images/news_image8.jpg', + 'reads': '754', + 'likes': '149', + 'content': 'More than 90% of enterprises say that fully autonomous driving data center network is their goal to achieve business agility, flexibility, and cost-effectiveness. This is a key research result in the data center network Autonomous Driving Index Report released by Huawei and IDC. Autonomous driving data center network helps enterprises restructure network architectures and operation models and enhance business resilience and continuity. In addition, regardless of the current level of data center network automation, IDC offers some guidance on how enterprises can move forward and move towards full automation.' + }, + { + 'title': 'One optical fiber lights up a green smart room', + 'type': 'Internet', + 'imgUrl': '/common/images/news_image9.jpg', + 'reads': '631', + 'likes': '714', + 'content': "At the 2020 China Real Estate Development Summit held in Guangzhou, Jin Yuzhi, President of Huawei's Transmission and Access Product Line, delivered a keynote speech entitled \"One Fiber Lights Green Smart Rooms\" to discuss the convergence development trend of optical networks and real estate industries, proposes that optical fibers are the standard configuration of F5G smart real estate, and shares seven reasons for choosing Fiber to the Room (FTTR) all-optical home networking, we call on industry partners to work together to build an F5G real gigabit all-optical room ecosystem." + }, + { + 'title': 'BWS2020: Accelerate Network Autonomy and Enable Agile Business', + 'type': 'Internet', + 'imgUrl': '/common/images/news_image10.jpg', + 'reads': '53', + 'likes': '824', + 'content': "Currently, millions of enterprises embrace changes and accelerate their cloudification. SaaS traffic surges. Enterprise cloudification and multi-cloud collaboration become the new focus of cloud-network synergy . To address this challenge, Guo Dazheng, president of Huawei's data communications field, said: \"In cloud-network scenarios, iMaster NCE implements network as a service to help carriers provide cloud-network integration services and meet enterprise cloud access requirements.\" In 5G transport scenarios, improve the automation capability of the entire process of planning, construction, maintenance, and optimization to meet the requirements of large-scale 5G network construction and cloud network cost reduction and efficiency improvement." + }, + { + 'title': 'Trust technology, embrace openness, and share the world prosperity brought by technology', + 'type': 'Game', + 'imgUrl': '/common/images/news_image11.jpg', + 'reads': '1500', + 'likes': '3542', + 'content': "Huawei successfully held the TrustInTech 2020 online summit today. Ryan Ding, Executive Director of Huawei, President of the Carrier BG, and Jim Rogers, a senior Wall Street investor, GSMA Chief Marketing Officer Stephanie Lynch-Habib and other ICT industry experts and economists from around the world attended the summit. The summit pointed out that ICT has become a digital foundation for economic development and people's livelihood. In an era of accelerated commercial use of 5G, the world needs to embrace openness and cooperation to eliminate unnecessary resistance and fears about new technologies and transnational cooperation, thereby sharing the world prosperity brought by technology." + }, + { + 'title': 'Intelligent Twins Won the Leading Technology Achievement Award at the 7th World Internet Conference', + 'type': 'Game', + 'imgUrl': '/common/images/news_image12.jpg', + 'reads': '7451', + 'likes': '9511', + 'content': "Today, the Leading Technology Award was unveiled at the 7th World Internet Conference. As the industry's first systematic technical reference architecture for government and enterprise intelligence upgrade, intelligent virtual appliances have been recognized by experts and judges and won the Leading Scientific Achievement Award for their exploration and practice in various industries. This is the fifth time Huawei has won this award since 2016. The World Internet Leading Science and Technology Award showcases the latest technologies in the global ICT field and focuses on the best practices of innovative technologies in the fields of science and technology fight against epidemics, recovery of work, and promotion of digital economic development and cooperation." + }, + { + 'title': '4G/5G FWA, New Engine for Revenue Growth', + 'type': 'Health', + 'imgUrl': '/common/images/news_image13.jpg', + 'reads': '445', + 'likes': '872', + 'content': 'The reason why FWA is growing so fast is that it provides new opportunities for carriers in the consumer market. For example, a Philippine operator used 4G FWA to rapidly develop home broadband users. According to its third quarter financial report, the operator has successfully developed 2.78 million new users this year, accounting for 80% of the total broadband users. The percentage of broadband revenue increased from 12.3% in 2017 to 17.9%. With the development of wireless technologies, 5G FWA can provide gigabit home access experience similar to that of optical fibers, meeting services such as 4K/8K HD video and AR/VR interactive experience.' + }, + { + 'title': 'Down! CPI released in November! These things are cheap', + 'type': 'Finance', + 'imgUrl': '/common/images/news_image14.jpg', + 'reads': '734', + 'likes': '8788', + 'content': 'Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.' + }, + { + 'title': 'Comedy movie "Big Red Envelope" is set to celebrate the New Year', + 'type': 'Technology', + 'imgUrl': '/common/images/news_image15.jpg', + 'reads': '1010', + 'likes': '3534', + 'content': 'Comedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New YearComedy movie "Big Red Envelope" is set to celebrate the New Year' + }, + { + 'title': 'Three living things are smart', + 'type': 'Sport', + 'imgUrl': '/common/images/news_image16.jpg', + 'reads': '1243', + 'likes': '9141', + 'content': 'Lifan said at the press conference: "Retrospective on the journey, we have always adhered to the spirit of initiative, innovation and science. Build core capabilities in terms of networks, technologies, and platforms, and deliver excellent services, technologies, and quality. Internal maintenance, optimization, and sharing are in place. Carriers, equipment vendors, and partners are working together to build an end-to-end network capability and win-win ecosystem to provide users with the best 5G experience and services."' + }, + { + 'title': 'Maximizing the Value of Wireless Networks and Ushering in the Golden Decade of 5G', + 'type': 'Internet', + 'imgUrl': '/common/images/news_image17.jpg', + 'reads': '7574', + 'likes': '1439', + 'content': 'The 5G industry is developing faster than the previous standards. Currently, there are more than 100 5G commercial networks around the world, and the price of entry-level 5G mobile phones has fallen to CNY1,000, which has led to the rapid growth of 5G users worldwide. Thanks to this, leading operators have enjoyed the data dividend brought by 5G. The multi-dimensional package design and 5G message and 5G new communication services are upgraded to increase the ARPU of 5G users to different degrees.\nTo promote the further development of 5G networks and encourage more users to choose and prefer 5G networks, operators need to build 5G top-quality networks for individual users to achieve full-scenario coverage in densely populated urban areas, suburban areas, and indoor areas, allowing mobile phone users to access 5G services anytime, anywhere. In addition, 5G connection experience is optimized to ensure consistent user experience.' + }, + { + 'title': 'Technology Helps Art, Leads a New Era', + 'type': 'Game', + 'imgUrl': '/common/images/news_image18.jpg', + 'reads': '6311', + 'likes': '7114', + 'content': "Zhang Wenlin spoke highly of the \"Dance Storm\". He believes that since the second season's premiere, the show has brought the contestants' exquisite dance moves, the wonderful host of Mr Ho Kung, the excellent comments of the judges' tutors, and the exquisite design of the staff to the audience, dedicate a beautiful visual feast! To help achieve fantastic visual effects, Hunan Radio and TV set up a joint team with Huawei to develop a spatio-temporal condensation system for Dance Storm 2. The system supports AI algorithms such as intelligent fast focusing, butterfly shooting, zoom-in, and multi-focus, with the help of the video 3.0+ platform of device-cloud synergy, the program team has made several industry-leading achievements, such as the three-dimensional storm moment with fantastic visual changes, free-view Dance Storm program with interactive control and rotation, and dance Storm with 360-degree panoramic view. VR programs." + }, + { + 'title': 'Open Intelligent Twin Ecosystem Is the Key to All-Scenario Intelligence', + 'type': 'Health', + 'imgUrl': '/common/images/news_image19.jpg', + 'reads': '6341', + 'likes': '7164', + 'content': 'Intelligent upgrade will build core competitiveness in various industries. Huawei works with partners to integrate 5G, cloud, AI, intelligent edge, and industry applications to form an integrated intelligent system and create industry-leading smart experience. In the transportation industry, the abolition of highway toll stations at the provincial boundary enables fast and insensitive traffic, greatly improving traffic efficiency and reducing logistics transportation costs. Intelligent cameras are deployed on highway portals to collect vehicle traffic data 24 hours a day and send the data to the cloud in real time over the high-speed network for real-time charging. In addition, AI models trained on the cloud can be pushed to the edge so that cameras can have capabilities such as license plate recognition and vehicle feature extraction, and the capabilities can be continuously evolved. For example, in extreme weather conditions such as rain and snow, one-click upgrade can be performed on the cloud.' + } +]; export default { - data() { - return { - titleList: titles, - newsList: newsData + data() { + return { + titleList: titles, + newsList: newsData + }; + }, + onInit() { + console.log('onInit::' + titles); + }, + // 选择新闻类型 + changeNewsType: function(e) { + const type = titles[e.index].name; + this.newsList = []; + if (type === 'All') { + // 展示全部新闻 + this.newsList = newsData; + } else { + // 分类展示新闻 + const newsArray = []; + for (const news of newsData) { + if (news.type === type) { + newsArray.push(news); } - }, - onInit() { - console.log("onInit::" + titles) - }, - changeNewsType: function (e) { - var type = titles[e.index].name; - this.newsList = []; - if (type === "All") { - this.newsList = newsData; - } else { - var newsArray = []; - for (var news of newsData) { - if (news.type === type) { - newsArray.push(news); - } - } - this.newsList = newsArray; - } - }, - startAbilityContinuation(news) { - var params; - params = { - title: news.title, - type: news.type, - imgUrl: news.imgUrl, - reads: news.reads, - likes: news.likes, - content: news.content, - }; - var wantValue = { - bundleName: 'com.huawei.newsdemooh', - abilityName: 'com.huawei.newsdemooh.MainAbility2', - deviceId: '', - parameters: params - }; - - featureAbility.startAbility({ - want: wantValue - }).then((data) => { - console.info('featureAbility.startAbility finished, ' + JSON.stringify(data)); - }); - console.info('featureAbility.startAbility want=' + JSON.stringify(wantValue)); - console.info('featureAbility.startAbility end'); - }, -} + } + this.newsList = newsArray; + } + }, + itemClick(news) { + // 跳转到详情页面 + router.push({ + uri: 'pages/detail/detail', + params: { + 'title': news.title, + 'type': news.type, + 'imgUrl': news.imgUrl, + 'reads': news.reads, + 'likes': news.likes, + 'content': news.content + } + }); + } +}; diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/data/data.js b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/data/data.js deleted file mode 100644 index 60214269a91ee63c70573ac503af5868c3afa08a..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/data/data.js +++ /dev/null @@ -1,182 +0,0 @@ - -export const titles= [ - { - "name": "All" - }, - { - "name": "Health" - }, - { - "name": "Finance" - }, - { - "name": "Technology" - }, - { - "name": "Sport" - }, - { - "name": "Internet" - }, - { - "name": "Game" - } -] - -export const newsData = [ - { - "title": "Best Enterprise Wi-Fi Network Award of the Wireless Broadband Alliance 2020", - "type": "Health", - "imgUrl": "/common/images/news_image1.jpg", - "reads": "54", - "likes": "81", - "content": "Recently, at the Wireless Broadband Alliance (WBA), an international industry organization, Huawei's AirEngine Wi-Fi 6 Solution Helps Factory Digital Transformation WBA 2020 Wi-Fi Industry Best Enterprise Wi-Fi Network Award. This is the first time that a Chinese Wi-Fi 6 vendor has won this award, which reflects the full recognition of Huawei AirEngine Wi-Fi 6 by global enterprise users." - }, - { - "title": "Latest technology and industry weather vane", - "type": "Health", - "imgUrl": "/common/images/news_image2.jpg", - "reads": "100", - "likes": "354", - "content": "With the large-scale commercial use of new technologies such as 5G, IoT, cloud computing, and AI, industry digital transformation has entered deep water. In addition, the sudden epidemic and carbon-neutral targets accelerate the transformation of society towards intelligence. When energy technologies are combined with power electronics and digital technologies, what direction will site energy develop?" - }, - { - "title": "Openness and Cooperation Facilitate Industry Upgrade", - "type": "Finance", - "imgUrl": "/common/images/news_image3.jpg", - "reads": "74", - "likes": "91", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." - }, - { - "title": "High-voltage super-fast charging is an inevitable trend", - "type": "Finance", - "imgUrl": "/common/images/news_image4.jpg", - "reads": "44", - "likes": "82", - "content": "Consumers have a lot of doubts about buying electric cars, compared to fuel cars. Wang Chao pointed out that among the factors affecting the purchase of electric vehicles, charging problems account for 80 percent, with a small number of charging piles (currently, the ratio of piles is 3.2:1) and a long charging time being the first to bear the brunt. As a result, many players in the charging infrastructure sector are looking for a break. To alleviate consumers' pain points of poor charging experience, we need to improve the pile ratio and shorten the charging time to meet consumers' requirements for fast charging." - }, - { - "title": "Huawei Releases the New Trend of Modular Power Supply, Facilitating Industry Upgrade Through Open Cooperation", - "type": "Technology", - "imgUrl": "/common/images/news_image5.jpg", - "reads": "73", - "likes": "888", - "content": "Under the background of new infrastructure construction, digital transformation will face great pressure in power consumption. According to analysis data, it is estimated that the number of communication sites will increase to 70 million by 2025, and the annual power consumption will exceed 660 billion kWh. The data center will increase to 24 million racks, and the annual power consumption will exceed 950 billion kWh. In pan-industrial scenarios, the annual power consumption of rail transportation and industrial manufacturing alone will exceed 16 trillion kWh. There are 40 billion smart terminals, and the annual power consumption will reach 210 billion kWh. The 40 billion mobile terminals under the 21 billion kWh power are driven by the transformation of social media and digital life." - }, - { - "title": "Ten Future Trends of Digital Energy", - "type": "Technology", - "imgUrl": "/common/images/news_image6.jpg", - "reads": "100", - "likes": "354", - "content": "Energy digitalization is an inevitable trend. Innovative integration of digital and energy technologies enables end-to-end visual, manageable, and controllable intelligent management of energy infrastructure, improving energy efficiency.\nGreen power will benefit thousands of industries and households in the future. Green power, represented by PV, will become the main energy source. The era of price-effective PV is coming, and the integration of distributed power generation and solar storage will become an inevitable trend. Green Power will also help the ICT industry reduce its carbon footprint. In the future, we will build a \"zero-carbon network\" and \"zero-carbon\" data center. In addition, Huawei proposed the trend of full-link efficiency for the first time and implemented global optimization in terms of architecture and system." - }, - { - "title": "Ascend Helps Industry, Learning, and Research Promote AI Industry Development in the National AI Contest", - "type": "Sport", - "imgUrl": "/common/images/news_image7.jpg", - "reads": "123", - "likes": "911", - "content": "The holding of the National AI Contest further fulfilled the requirements of the Ministry of Science and Technology and the Ministry of Industry and Information Technology for Shenzhen to build the national new-generation AI innovation and development trial zone and the AI innovation and application pilot zone. It also promoted the integration and development of innovation elements such as industry, academia, capital, and talent, create an AI innovation atmosphere. Huawei has co-hosted two National AI Competitions in a row, aiming to promote technological progress, industrial upgrade, economic transformation, and social progress, and jointly promote the implementation of AI technologies. This is the most practical point for Huawei and the National AI Competition." - }, - { - "title": "Enterprise data centers are moving towards autonomous driving network", - "type": "Sport", - "imgUrl": "/common/images/news_image8.jpg", - "reads": "754", - "likes": "149", - "content": "More than 90% of enterprises say that fully autonomous driving data center network is their goal to achieve business agility, flexibility, and cost-effectiveness. This is a key research result in the data center network Autonomous Driving Index Report released by Huawei and IDC. Autonomous driving data center network helps enterprises restructure network architectures and operation models and enhance business resilience and continuity. In addition, regardless of the current level of data center network automation, IDC offers some guidance on how enterprises can move forward and move towards full automation." - }, - { - "title": "One optical fiber lights up a green smart room", - "type": "Internet", - "imgUrl": "/common/images/news_image9.jpg", - "reads": "631", - "likes": "714", - "content": "At the 2020 China Real Estate Development Summit held in Guangzhou, Jin Yuzhi, President of Huawei's Transmission and Access Product Line, delivered a keynote speech entitled \"One Fiber Lights Green Smart Rooms\" to discuss the convergence development trend of optical networks and real estate industries, proposes that optical fibers are the standard configuration of F5G smart real estate, and shares seven reasons for choosing Fiber to the Room (FTTR) all-optical home networking, we call on industry partners to work together to build an F5G real gigabit all-optical room ecosystem." - }, - { - "title": "BWS2020: Accelerate Network Autonomy and Enable Agile Business", - "type": "Internet", - "imgUrl": "/common/images/news_image10.jpg", - "reads": "53", - "likes": "824", - "content": "Currently, millions of enterprises embrace changes and accelerate their cloudification. SaaS traffic surges. Enterprise cloudification and multi-cloud collaboration become the new focus of cloud-network synergy . To address this challenge, Guo Dazheng, president of Huawei's data communications field, said: \"In cloud-network scenarios, iMaster NCE implements network as a service to help carriers provide cloud-network integration services and meet enterprise cloud access requirements.\" In 5G transport scenarios, improve the automation capability of the entire process of planning, construction, maintenance, and optimization to meet the requirements of large-scale 5G network construction and cloud network cost reduction and efficiency improvement." - }, - { - "title": "Trust technology, embrace openness, and share the world prosperity brought by technology", - "type": "Game", - "imgUrl": "/common/images/news_image11.jpg", - "reads": "1500", - "likes": "3542", - "content": "Huawei successfully held the TrustInTech 2020 online summit today. Ryan Ding, Executive Director of Huawei, President of the Carrier BG, and Jim Rogers, a senior Wall Street investor, GSMA Chief Marketing Officer Stephanie Lynch-Habib and other ICT industry experts and economists from around the world attended the summit. The summit pointed out that ICT has become a digital foundation for economic development and people's livelihood. In an era of accelerated commercial use of 5G, the world needs to embrace openness and cooperation to eliminate unnecessary resistance and fears about new technologies and transnational cooperation, thereby sharing the world prosperity brought by technology." - }, - { - "title": "Intelligent Twins Won the Leading Technology Achievement Award at the 7th World Internet Conference", - "type": "Game", - "imgUrl": "/common/images/news_image12.jpg", - "reads": "7451", - "likes": "9511", - "content": "Today, the Leading Technology Award was unveiled at the 7th World Internet Conference. As the industry's first systematic technical reference architecture for government and enterprise intelligence upgrade, intelligent virtual appliances have been recognized by experts and judges and won the Leading Scientific Achievement Award for their exploration and practice in various industries. This is the fifth time Huawei has won this award since 2016. The World Internet Leading Science and Technology Award showcases the latest technologies in the global ICT field and focuses on the best practices of innovative technologies in the fields of science and technology fight against epidemics, recovery of work, and promotion of digital economic development and cooperation." - }, - { - "title": "4G/5G FWA, New Engine for Revenue Growth", - "type": "Health", - "imgUrl": "/common/images/news_image13.jpg", - "reads": "445", - "likes": "872", - "content": "The reason why FWA is growing so fast is that it provides new opportunities for carriers in the consumer market. For example, a Philippine operator used 4G FWA to rapidly develop home broadband users. According to its third quarter financial report, the operator has successfully developed 2.78 million new users this year, accounting for 80% of the total broadband users. The percentage of broadband revenue increased from 12.3% in 2017 to 17.9%. With the development of wireless technologies, 5G FWA can provide gigabit home access experience similar to that of optical fibers, meeting services such as 4K/8K HD video and AR/VR interactive experience." - }, - { - "title": "Down! CPI released in November! These things are cheap", - "type": "Finance", - "imgUrl": "/common/images/news_image14.jpg", - "reads": "734", - "likes": "8788", - "content": "Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap.Down! CPI released in November! These things are cheap." - }, - { - "title": "Comedy movie \"Big Red Envelope\" is set to celebrate the New Year", - "type": "Technology", - "imgUrl": "/common/images/news_image15.jpg", - "reads": "1010", - "likes": "3534", - "content": "Comedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New YearComedy movie \"Big Red Envelope\" is set to celebrate the New Year" - }, - { - "title": "Three living things are smart", - "type": "Sport", - "imgUrl": "/common/images/news_image16.jpg", - "reads": "1243", - "likes": "9141", - "content": "Lifan said at the press conference: \"Retrospective on the journey, we have always adhered to the spirit of initiative, innovation and science. Build core capabilities in terms of networks, technologies, and platforms, and deliver excellent services, technologies, and quality. Internal maintenance, optimization, and sharing are in place. Carriers, equipment vendors, and partners are working together to build an end-to-end network capability and win-win ecosystem to provide users with the best 5G experience and services.\"" - }, - { - "title": "Maximizing the Value of Wireless Networks and Ushering in the Golden Decade of 5G", - "type": "Internet", - "imgUrl": "/common/images/news_image17.jpg", - "reads": "7574", - "likes": "1439", - "content": "The 5G industry is developing faster than the previous standards. Currently, there are more than 100 5G commercial networks around the world, and the price of entry-level 5G mobile phones has fallen to CNY1,000, which has led to the rapid growth of 5G users worldwide. Thanks to this, leading operators have enjoyed the data dividend brought by 5G. The multi-dimensional package design and 5G message and 5G new communication services are upgraded to increase the ARPU of 5G users to different degrees.\nTo promote the further development of 5G networks and encourage more users to choose and prefer 5G networks, operators need to build 5G top-quality networks for individual users to achieve full-scenario coverage in densely populated urban areas, suburban areas, and indoor areas, allowing mobile phone users to access 5G services anytime, anywhere. In addition, 5G connection experience is optimized to ensure consistent user experience." - }, - { - "title": "Technology Helps Art, Leads a New Era", - "type": "Game", - "imgUrl": "/common/images/news_image18.jpg", - "reads": "6311", - "likes": "7114", - "content": "Zhang Wenlin spoke highly of the \"Dance Storm\". He believes that since the second season's premiere, the show has brought the contestants' exquisite dance moves, the wonderful host of Mr Ho Kung, the excellent comments of the judges' tutors, and the exquisite design of the staff to the audience, dedicate a beautiful visual feast! To help achieve fantastic visual effects, Hunan Radio and TV set up a joint team with Huawei to develop a spatio-temporal condensation system for Dance Storm 2. The system supports AI algorithms such as intelligent fast focusing, butterfly shooting, zoom-in, and multi-focus, with the help of the video 3.0+ platform of device-cloud synergy, the program team has made several industry-leading achievements, such as the three-dimensional storm moment with fantastic visual changes, free-view Dance Storm program with interactive control and rotation, and dance Storm with 360-degree panoramic view. VR programs." - }, - { - "title": "Open Intelligent Twin Ecosystem Is the Key to All-Scenario Intelligence", - "type": "Health", - "imgUrl": "/common/images/news_image19.jpg", - "reads": "6341", - "likes": "7164", - "content": "Intelligent upgrade will build core competitiveness in various industries. Huawei works with partners to integrate 5G, cloud, AI, intelligent edge, and industry applications to form an integrated intelligent system and create industry-leading smart experience. In the transportation industry, the abolition of highway toll stations at the provincial boundary enables fast and insensitive traffic, greatly improving traffic efficiency and reducing logistics transportation costs. Intelligent cameras are deployed on highway portals to collect vehicle traffic data 24 hours a day and send the data to the cloud in real time over the high-speed network for real-time charging. In addition, AI models trained on the cloud can be pushed to the edge so that cameras can have capabilities such as license plate recognition and vehicle feature extraction, and the capabilities can be continuously evolved. For example, in extreme weather conditions such as rain and snow, one-click upgrade can be performed on the cloud." - } -] - - - diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_good.png b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_good.png deleted file mode 100644 index e306e705fe96f10576fa393c3390ea63f26408dd..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_good.png and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_message.png b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_message.png deleted file mode 100644 index b81007d64cbe5265df414a6dab58cd103cd5a521..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_message.png and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_share.png b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_share.png deleted file mode 100644 index 1fb1cae93ea21b0712abc939b828ea92ffcb07f4..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_share.png and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_star.png b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_star.png deleted file mode 100644 index 5ace4c20d2f949b567fc960d205c345273fadee2..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/icon_star.png and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image1.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image1.jpg deleted file mode 100644 index bfe2ae5849d6b022c2eab195f0fc0c04721db285..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image1.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image10.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image10.jpg deleted file mode 100644 index 781936afc0354e0f22d1b77339968927c29ffb36..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image10.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image11.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image11.jpg deleted file mode 100644 index f2862e308f284c5cc87d06c5316d5edec86028f3..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image11.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image12.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image12.jpg deleted file mode 100644 index 0425178705c4e56888d7df2b308efdfcd7ac8640..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image12.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image13.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image13.jpg deleted file mode 100644 index b349d81e1dce2d2a553baaf26a5b7fde58d8beac..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image13.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image14.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image14.jpg deleted file mode 100644 index e3d1ca269b529e890a3e154ac081e93487f5743b..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image14.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image15.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image15.jpg deleted file mode 100644 index 54775977a85c165759a22b8c8e956ecc59603ff8..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image15.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image16.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image16.jpg deleted file mode 100644 index 17780bfc6f7f014b1920fa5159cb1a4699a5de49..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image16.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image17.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image17.jpg deleted file mode 100644 index a34dcd88e1507fd07d509fcffe024dfe7a59ab39..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image17.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image18.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image18.jpg deleted file mode 100644 index ad79353b9bcfb2cd5b05ef6296f29e3ac826d3ca..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image18.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image19.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image19.jpg deleted file mode 100644 index 5e8c9267e9632b829492f6d93bfebfcb9c0dc114..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image19.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image2.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image2.jpg deleted file mode 100644 index 2322f158e6a108b8a4f2bbcb20204bd7974c12d9..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image2.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image3.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image3.jpg deleted file mode 100644 index 6da8be18ed043a9fc815689e7482e9fe04969f1a..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image3.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image4.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image4.jpg deleted file mode 100644 index 78bfe6f367b9534e1236725b50a2b98934a76827..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image4.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image5.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image5.jpg deleted file mode 100644 index bda3780f9779e2169cea6b3cd0aae77bc6e6cc95..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image5.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image6.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image6.jpg deleted file mode 100644 index 60ebfaa4bd05ca32c40b99f247a9d2998d85dd69..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image6.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image7.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image7.jpg deleted file mode 100644 index bfc4fb58e7a5ca3062dc775721f9106d333adaec..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image7.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image8.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image8.jpg deleted file mode 100644 index e58a289f7d136043766f33f168a87af367c370f3..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image8.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image9.jpg b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image9.jpg deleted file mode 100644 index e7de107a86d8a741fa4112c3df79c60a1ac086e5..0000000000000000000000000000000000000000 Binary files a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/common/images/news_image9.jpg and /dev/null differ diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/i18n/en-US.json b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/i18n/en-US.json deleted file mode 100644 index 547e7e13afae9b28f836a4d857e576413ea82bc5..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/i18n/en-US.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "strings": { - "hello": "Hello", - "world": "World", - "page": "Second Page", - "next": "Next Page", - "back": "Back", - "localhost": "This device" - }, - "Files": { - } -} \ No newline at end of file diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/i18n/zh-CN.json b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/i18n/zh-CN.json deleted file mode 100644 index 38de361bd7bac39682ded8a4839f9cf7822fbdf0..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/i18n/zh-CN.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "strings": { - "hello": "您好", - "world": "世界", - "page": "第二页", - "next": "下一页", - "back": "返回", - "localhost": "本机" - }, - "Files": { - } -} \ No newline at end of file diff --git a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/pages/index/index.js b/Distributed/NewsDemo/entry/src/main/js/MainAbility2/pages/index/index.js deleted file mode 100644 index 5b0549627b830b1e0f030ed8b5b553c1c871dad4..0000000000000000000000000000000000000000 --- a/Distributed/NewsDemo/entry/src/main/js/MainAbility2/pages/index/index.js +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2021 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 router from '@system.router' -import featureAbility from '@ohos.ability.featureAbility'; -import RemoteDeviceModel from '../../../model/RemoteDeviceModel.js'; - -const REMOTE_ABILITY_STARTED = 'remoteAbilityStarted'; -var DEVICE_LIST_LOCALHOST; - -export default { - data: { - title: "", - type: "", - imgUrl: "", - reads: "", - likes: "", - content: "", - deviceList: [], - remoteDeviceModel: new RemoteDeviceModel(), - }, - onInit() { - console.info('onInit begin'); - DEVICE_LIST_LOCALHOST = { - name: this.$t('strings.localhost'), - id: 'localhost', - }; - this.deviceList = [DEVICE_LIST_LOCALHOST]; - this.restoreFromWant(); - console.info('onInit end'); - }, - - restoreFromWant() { - let self = this; - featureAbility.getWant((error, want) => { - console.info('MusicPlayer[IndexPage] featureAbility.getWant=' + JSON.stringify(want)); - var status = want.parameters; - this.title = status.title - this.type = status.type, - this.imgUrl = status.imgUrl, - this.reads = status.reads, - this.likes = status.likes, - this.content = status.content - }); - }, - - onContinueAbilityClick() { - console.info('onContinueAbilityClick begin'); - let self = this; - this.remoteDeviceModel.registerDeviceListCallback(() => { - console.info('registerDeviceListCallback, callback entered'); - var list = []; - list[0] = DEVICE_LIST_LOCALHOST; - var deviceList; - if (self.remoteDeviceModel.discoverList.length > 0) { - deviceList = self.remoteDeviceModel.discoverList; - } else { - deviceList = self.remoteDeviceModel.deviceList; - } - console.info('on remote device updated, count=' + deviceList.length); - for (var i = 0; i < deviceList.length; i++) { - console.info('device ' + i + '/' + deviceList.length + ' deviceId=' - + deviceList[i].deviceId + ' deviceName=' + deviceList[i].deviceName + ' deviceType=' - + deviceList[i].deviceType); - list[i + 1] = { - name: deviceList[i].deviceName, - id: deviceList[i].deviceId, - }; - } - self.deviceList = list; - }); - this.$element('continueAbilityDialog').show(); - this.isDialogShowing = true; - console.info('onContinueAbilityClick end'); - }, - startAbilityContinuation(deviceId, deviceName) { - - var params; - params = { - title: this.title, - type: this.type, - imgUrl: this.imgUrl, - reads: this.reads, - likes: this.likes, - content: this.content, - }; - - var wantValue = { - bundleName: 'com.huawei.newsdemooh', - abilityName: 'com.huawei.newsdemooh.MainAbility2', - deviceId: deviceId, - parameters: params - }; - - featureAbility.startAbility({ - want: wantValue - }).then((data) => { - console.info('featureAbility.startAbility finished, ' + JSON.stringify(data)); - }); - console.info('featureAbility.startAbility want=' + JSON.stringify(wantValue)); - console.info('featureAbility.startAbility end'); - }, - onRadioChange(inputValue, e) { - console.info('onRadioChange ' + inputValue + ', ' + e.value); - if (inputValue === e.value) { - if (e.value === 'localhost') { - this.$element('continueAbilityDialog').close(); - return; - } - if (this.remoteDeviceModel.discoverList.length > 0) { - console.info('continue to unauthed device'); - var name = null; - for (var i = 0; i < this.remoteDeviceModel.discoverList.length; i++) { - if (this.remoteDeviceModel.discoverList[i].deviceId === e.value) { - name = this.remoteDeviceModel.discoverList[i].deviceName; - break; - } - } - if (name == null) { - console.error('onRadioChange failed, can not get name from discoverList'); - return; - } - console.info('onRadioChange name=' + name); - - let self = this; - this.remoteDeviceModel.authDevice(e.value, () => { - console.info('auth and online finished'); - for (i = 0; i < self.remoteDeviceModel.deviceList.length; i++) { - if (self.remoteDeviceModel.deviceList[i].deviceName === name) { - this.startAbilityContinuation(self.remoteDeviceModel.deviceList[i].deviceId, self.remoteDeviceModel.deviceList[i].deviceName); - } - } - }); - } else { - console.info('continue to authed device'); - for (i = 0; i < this.remoteDeviceModel.deviceList.length; i++) { - if (this.remoteDeviceModel.deviceList[i].deviceId === e.value) { - this.startAbilityContinuation(this.remoteDeviceModel.deviceList[i].deviceId, this.remoteDeviceModel.deviceList[i].deviceName); - } - } - } - } - }, - onDestroy() { - console.info('onDestroy begin'); - this.remoteDeviceModel.unregisterDeviceListCallback(); - console.info('onDestroy end'); - }, - cancelDialog(e) { - this.remoteDeviceModel.unregisterDeviceListCallback(); - }, - onDismissDialogClicked(e) { - this.dismissDialog(); - }, - dismissDialog() { - this.$element('continueAbilityDialog').close(); - this.remoteDeviceModel.unregisterDeviceListCallback(); - }, - touchMove(e) { - if (e.direction == "right") { - this.appExit(); - } - }, - appExit() { - app.terminate() - } -} - - - diff --git a/Distributed/NewsDemo/entry/src/main/resources/base/element/string.json b/Distributed/NewsDemo/entry/src/main/resources/base/element/string.json index ad5f27c848ccb4d7bdbec708831b88ef83c72cdb..12afe66d861b4e3f5efda2893a7d609882173162 100644 --- a/Distributed/NewsDemo/entry/src/main/resources/base/element/string.json +++ b/Distributed/NewsDemo/entry/src/main/resources/base/element/string.json @@ -1,20 +1,12 @@ { "string": [ { - "name": "entry_MainAbility", + "name": "NewsClient", "value": "新闻" }, { "name": "mainability_description", "value": "JS_Empty Ability" - }, - { - "name": "mainability2_description", - "value": "JS_Empty Ability" - }, - { - "name": "entry_MainAbility2", - "value": "新闻" } ] } \ No newline at end of file diff --git a/Distributed/NewsDemo/screenshots/device/IMG_20211213_103011.jpg b/Distributed/NewsDemo/screenshots/device/IMG_20211213_103011.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5c162aaab1e9421bc1b7d2571728a840b85897d Binary files /dev/null and b/Distributed/NewsDemo/screenshots/device/IMG_20211213_103011.jpg differ diff --git a/Distributed/NewsDemo/screenshots/device/IMG_20211217_144057.jpg b/Distributed/NewsDemo/screenshots/device/IMG_20211217_144057.jpg new file mode 100644 index 0000000000000000000000000000000000000000..157e7be6e99ec8de3693331d74adae9b057298e5 Binary files /dev/null and b/Distributed/NewsDemo/screenshots/device/IMG_20211217_144057.jpg differ diff --git a/Distributed/NewsDemo/screenshots/device/icon-note.gif b/Distributed/NewsDemo/screenshots/device/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/Distributed/NewsDemo/screenshots/device/icon-note.gif differ diff --git a/Distributed/NewsDemo/screenshots/device/pin.png b/Distributed/NewsDemo/screenshots/device/pin.png new file mode 100644 index 0000000000000000000000000000000000000000..06badab0e9ffd8c87cc82e9f448f351a0d6f5bae Binary files /dev/null and b/Distributed/NewsDemo/screenshots/device/pin.png differ diff --git a/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001192761736.png b/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001192761736.png new file mode 100644 index 0000000000000000000000000000000000000000..193afe8f1731f9ee325ef32a049964049bca755d Binary files /dev/null and b/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001192761736.png differ diff --git a/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001193324850.png b/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001193324850.png new file mode 100644 index 0000000000000000000000000000000000000000..b16233d9c221e3b9b8661aea43652fc7e9e7ceab Binary files /dev/null and b/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001193324850.png differ diff --git a/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001206445177.png b/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001206445177.png new file mode 100644 index 0000000000000000000000000000000000000000..9b4259264d26f46c3e5edc4e0a68f33568a544dc Binary files /dev/null and b/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001206445177.png differ diff --git a/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001238284773.png b/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001238284773.png new file mode 100644 index 0000000000000000000000000000000000000000..4dbcf2fd51ae506fcb6f9e63b3995b7ac6c8ce4b Binary files /dev/null and b/Distributed/NewsDemo/screenshots/device/zh-cn_image_0000001238284773.png differ diff --git "a/Distributed/NewsDemo/screenshots/device/\344\277\241.png" "b/Distributed/NewsDemo/screenshots/device/\344\277\241.png" new file mode 100644 index 0000000000000000000000000000000000000000..49074a428c2308a29171362bf46171d80c8927f0 Binary files /dev/null and "b/Distributed/NewsDemo/screenshots/device/\344\277\241.png" differ diff --git "a/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\276-0.png" "b/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\276-0.png" new file mode 100644 index 0000000000000000000000000000000000000000..d8ceebd14d975107a4f873a9a39e65a47374d2e3 Binary files /dev/null and "b/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\276-0.png" differ diff --git "a/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\276.png" "b/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\276.png" differ diff --git "a/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\2761222.png" "b/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\2761222.png" new file mode 100644 index 0000000000000000000000000000000000000000..f0f3ce7042c831dc7abab93f5a3d4cd709aee9df Binary files /dev/null and "b/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\2761222.png" differ diff --git "a/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\27612222.png" "b/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\27612222.png" new file mode 100644 index 0000000000000000000000000000000000000000..05e6fe3a0e5fc1626be4155b035ffe7c0477551c Binary files /dev/null and "b/Distributed/NewsDemo/screenshots/device/\346\210\252\345\233\27612222.png" differ diff --git "a/Distributed/NewsDemo/screenshots/device/\347\241\256\350\256\244.png" "b/Distributed/NewsDemo/screenshots/device/\347\241\256\350\256\244.png" new file mode 100644 index 0000000000000000000000000000000000000000..4e8a02292e7dfdc20865a8befb3e23ecf0053222 Binary files /dev/null and "b/Distributed/NewsDemo/screenshots/device/\347\241\256\350\256\244.png" differ diff --git "a/Distributed/NewsDemo/screenshots/device/\351\237\263\344\271\220.png" "b/Distributed/NewsDemo/screenshots/device/\351\237\263\344\271\220.png" new file mode 100644 index 0000000000000000000000000000000000000000..a473a3a4a39363f60b6b36cdd930b23aeeab9445 Binary files /dev/null and "b/Distributed/NewsDemo/screenshots/device/\351\237\263\344\271\220.png" differ diff --git a/Distributed/RemoteStartFA/README.md b/Distributed/RemoteStartFA/README.md index 9815ca4317344882b0cce041f5c708785cbac947..39f78762b6365be7e4f79a63fb1ae7447919e2ce 100644 --- a/Distributed/RemoteStartFA/README.md +++ b/Distributed/RemoteStartFA/README.md @@ -1,3 +1,676 @@ -# RemoteStartFA -简介 -• 此Demo使用openHarmony的分布式拉起能力,我们将会通过一个简单的样例,实现简单拉起分布式设备中应用的FA的效果 +# 1.介绍 + +OpenHarmony提供了分布式能力,能够实现在同一网络下对远程设备Ability的拉起。本篇Codelab,我们将一起开启OpenHarmony分布式调度启动远程FA之路。本教程将给大家分享分布式能力中最基本的分布式拉起是如何实现的。 + +实现效果如下: + +![](figures/VID_20211214_114528-00_00_00-00_00_30.gif) + +# 2.相关概念 + +**[dialog组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-container-dialog.md):**自定义弹窗容器组件。 + +**[button组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-button.md):**按钮组件。 + +**[通用事件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-common-events.md)**:事件绑定在组件上,当组件达到事件触发条件时,会执行JS中对应的事件回调函数,实现页面UI视图和页面JS逻辑层的交互。 + + + +# 3.搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 4.分布式组网 + +本章节以系统自带的音乐播放器为例,介绍如何完成两台设备的分布式组网。 + +1. 硬件准备:准备两台烧录相同的版本系统的**Hi3516DV300**开发板A,B。 + +2. 两个开发板A,B配置在同一个WiFi网络之下。 + + 打开设置--\>WLAN--\>点击右侧WiFi开关--\>点击目标WiFi并输入密码。 + + ![](figures/IMG_20211217_144057.jpg) + +3. 将设备A,B设置为互相信任的设备。 + + - 找到系统应用“音乐”。 + + ![](figures/音乐.png) + + - 设备A打开音乐,点击左下角流转按钮,弹出列表框,在列表中会展示远端设备的id。 + + ![](figures/IMG_20211213_103011.jpg) + + - 选择远端设备B的id,另一台开发板(设备B)会弹出验证的选项框。 + + ![](figures/信.png) + + - 设备B点击允许,设备B将会弹出随机PIN码,将设备B的PIN码输入到设备A的PIN码填入框中。 + + ![](figures/pin.png)![](figures/确认.png) + + 配网完毕。 + +# 5.将组件添加到布局中 + +1. 在src/main/js/default/pages/index/index.hml中添加一个button按钮,来为实现点击button按钮弹出对话框做准备。 + + ``` +
+ +
+ ``` + +2. 在src/main/js/default/pages/index/index.hml中添加对话框组件,用于弹出设备列表。 + + ``` +
+ ... + +
+ 选择设备 + + +
+ + +
+
+
+
+ +
+
+
+
+ ``` + +# 6.为页面设计样式 + +这部分定义了整个页面中各个组件的样式,有关CSS更多的知识可以参考[CSS语法参考](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-framework-syntax-css.md),在index.css中先添加如下代码: + +``` +.container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + align-content: center; + left: 0px; + top: 0px; + width: 100%; + height: 100%; +} + +.btn { + margin-top: 40%; + width: 70%; + height: 100px; + font-size: 40px; + background-color: #2788D9; +} +.container { + width: 100%; + height: 100%; + flex-direction: column; + justify-content: space-between; + align-items: center; + background-image: url(common/media/bg_blurry.png); + background-size: cover; + background-position: center center; +} + +.title_section { + margin-top: 150px; + margin-bottom: 10px; + flex-direction: row; + justify-content: center; +} +.title { + height: 64px; + font-size: 48px; + color: #FFF; + margin-bottom: 10px; + text-align: center; +} +.album_section { + width: 100%; + aspect-ratio: 1; + flex-direction: row; + align-items: center; + margin-top: 25px; + margin-bottom: 25px; +} +.album_image { + align-items: center; + object-fit: contain; +} +.progress_section { + margin-bottom: 100px; + flex-direction: column; +} +.timer { + width: 100%; + flex-direction: row; + justify-content: space-between; + margin-bottom: 12px; +} +.progress_time { + height: 32px; + color: #FFF; + text-align: center; + font-size: 24px; +} +.total_time { + height: 32px; + color: #FFF; + text-align: center; + font-size: 24px; +} +.music_slider { + width: 100%; + color: #64CCE7FF; + padding-left: 0; + padding-right: 0; +} + +.control_section { + width: 100%; + justify-content: space-between; + flex-direction: row; +} +.control_button { + height: 96px; + width: 96px; +} + +.txt { + color: #000; + font-weight: bold; + font-size: 39px; +} +.dialog-main { + width: 500px; +} +.dialog-div { + flex-direction: column; + align-items: center; +} +.dialog_title_text { + width: 434px; + height: 80px; + font-size: 32px; + font-weight: 600; +} +.inner-btn { + width: 400px; + height: 120px; + justify-content: space-around; + align-items: center; +} + +.dialog_cancel_button { + width: 100%; + font-size: 32px; +} +.dialog_device_list { + width: 434px; + max-height: 150px; +} +.device_list_item { + width: 434px; + height: 80px; + flex-direction: row; + align-items: center; +} +.device_item_radio { +} +.device_item_title { + width: 80%; + height: 80px; + text-align: start; +} +@media screen and (device-type: tablet) and (orientation: landscape) { +} +@media screen and (device-type: wearable) { +} +@media screen and (device-type: tv) { +} +@media screen and (device-type: phone) and (orientation: landscape) { +} +``` + +# 7.创建远程设备对象类,并编写基本方法 + +- 在js目录下创建model文件夹,并在model文件夹中创建RemoteDeviceModel.js文件。 + +![](figures/远程.png) + +- 创建设备对象类。 + +``` +import deviceManager from '@ohos.distributedHardware.deviceManager'; +var SUBSCRIBE_ID = 100; +export default class RemoteDeviceModel { + // 选中的设备列表 + deviceList = []; + // 发现的设备列表 + discoverList = []; + // 回调方法 + callback; + // 身份验证回调 + authCallback = null; + // 设备管理类对象 + #deviceManager; + // 构造方法 + constructor() { + } +} +``` + +- 定义并实现一些基本方法。 + +``` +export default class RemoteDeviceModel { + ... + //注册设备回调方法 + registerDeviceListCallback(callback) { + if (typeof (this.#deviceManager) === 'undefined') { + console.log('CookBook[RemoteDeviceModel] deviceManager.createDeviceManager begin'); + let self = this; + deviceManager.createDeviceManager('com.ohos.distributedRemoteStartFA', (error, value) => { + if (error) { + console.error('createDeviceManager failed.'); + return; + } + self.#deviceManager = value; + self.registerDeviceListCallback_(callback); + console.log('CookBook[RemoteDeviceModel] createDeviceManager callback returned, error=' + error + ' value=' + value); + }); + console.log('CookBook[RemoteDeviceModel] deviceManager.createDeviceManager end'); + } else { + this.registerDeviceListCallback_(callback); + } + } + //注册设备回调子方法 + registerDeviceListCallback_(callback) { + console.info('CookBook[RemoteDeviceModel] registerDeviceListCallback'); + this.callback = callback; + if (this.#deviceManager == undefined) { + console.error('CookBook[RemoteDeviceModel] deviceManager has not initialized'); + this.callback(); + return; + } + + console.info('CookBook[RemoteDeviceModel] getTrustedDeviceListSync begin'); + var list = this.#deviceManager.getTrustedDeviceListSync(); + console.info('CookBook[RemoteDeviceModel] getTrustedDeviceListSync end, deviceList=' + JSON.stringify(list)); + if (typeof (list) != 'undefined' && typeof (list.length) != 'undefined') { + this.deviceList = list; + } + this.callback(); + console.info('CookBook[RemoteDeviceModel] callback finished'); + + let self = this; + this.#deviceManager.on('deviceStateChange', (data) => { + console.info('CookBook[RemoteDeviceModel] deviceStateChange data=' + JSON.stringify(data)); + switch (data.action) { + case 0: + self.deviceList[self.deviceList.length] = data.device; + console.info('CookBook[RemoteDeviceModel] online, updated device list=' + JSON.stringify(self.deviceList)); + self.callback(); + if (self.authCallback != null) { + self.authCallback(); + self.authCallback = null; + } + break; + case 2: + if (self.deviceList.length > 0) { + for (var i = 0; i < self.deviceList.length; i++) { + if (self.deviceList[i].deviceId === data.device.deviceId) { + self.deviceList[i] = data.device; + break; + } + } + } + console.info('CookBook[RemoteDeviceModel] change, updated device list=' + JSON.stringify(self.deviceList)); + self.callback(); + break; + case 1: + if (self.deviceList.length > 0) { + var list = []; + for (var i = 0; i < self.deviceList.length; i++) { + if (self.deviceList[i].deviceId != data.device.deviceId) { + list[i] = data.device; + } + } + self.deviceList = list; + } + console.info('CookBook[RemoteDeviceModel] offline, updated device list=' + JSON.stringify(data.device)); + self.callback(); + break; + default: + break; + } + }); + this.#deviceManager.on('deviceFound', (data) => { + console.info('CookBook[RemoteDeviceModel] deviceFound data=' + JSON.stringify(data)); + console.info('CookBook[RemoteDeviceModel] deviceFound self.deviceList=' + self.deviceList); + console.info('CookBook[RemoteDeviceModel] deviceFound self.deviceList.length=' + self.deviceList.length); + for (var i = 0; i < self.discoverList.length; i++) { + if (self.discoverList[i].deviceId === data.device.deviceId) { + console.info('CookBook[RemoteDeviceModel] device founded, ignored'); + return; + } + } + self.discoverList[self.discoverList.length] = data.device; + self.callback(); + }); + this.#deviceManager.on('discoverFail', (data) => { + console.info('CookBook[RemoteDeviceModel] discoverFail data=' + JSON.stringify(data)); + }); + this.#deviceManager.on('serviceDie', () => { + console.error('CookBook[RemoteDeviceModel] serviceDie'); + }); + + SUBSCRIBE_ID = Math.floor(65536 * Math.random()); + var info = { + subscribeId: SUBSCRIBE_ID, + mode: 0xAA, + medium: 2, + freq: 2, + isSameAccount: false, + isWakeRemote: true, + capability: 0 + }; + console.info('CookBook[RemoteDeviceModel] startDeviceDiscovery ' + SUBSCRIBE_ID); + this.#deviceManager.startDeviceDiscovery(info); + } + //身份验证 + authDevice(deviceId, callback) { + console.info('CookBook[RemoteDeviceModel] authDevice ' + deviceId); + for (var i = 0; i < this.discoverList.length; i++) { + if (this.discoverList[i].deviceId === deviceId) { + console.info('CookBook[RemoteDeviceModel] device founded, ignored'); + let extraInfo = { + "targetPkgName": 'com.ohos.distributedRemoteStartFA', + "appName": 'demo', + "appDescription": 'demo application', + "business": '0' + }; + let authParam = { + "authType": 1, + "appIcon": '', + "appThumbnail": '', + "extraInfo": extraInfo + }; + console.info('CookBook[RemoteDeviceModel] authenticateDevice ' + JSON.stringify(this.discoverList[i])); + let self = this; + this.#deviceManager.authenticateDevice(this.discoverList[i], authParam, (err, data) => { + if (err) { + console.info('CookBook[RemoteDeviceModel] authenticateDevice failed, err=' + JSON.stringify(err)); + self.authCallback = null; + } else { + console.info('CookBook[RemoteDeviceModel] authenticateDevice succeed, data=' + JSON.stringify(data)); + self.authCallback = callback; + } + }); + } + } + } + //取消注册设备回调方法 + unregisterDeviceListCallback() { + console.info('CookBook[RemoteDeviceModel] stopDeviceDiscovery ' + SUBSCRIBE_ID); + this.#deviceManager.stopDeviceDiscovery(SUBSCRIBE_ID); + this.#deviceManager.off('deviceStateChange'); + this.#deviceManager.off('deviceFound'); + this.#deviceManager.off('discoverFail'); + this.#deviceManager.off('serviceDie'); + this.deviceList = []; + } +} +``` + +# 8.为组件添加相应的事件 + +我们已经定义好了布局和样式,接下来,我们一起来完成点击不同的button呈现不同dialog效果的功能。 + +首先我们了解一下dialog主要有哪些API,如下所示: + +dialog支持如下事件: + + + + + + + + + + + + + +

名称

+

参数

+

描述

+

cancel

+

-

+

用户点击非dialog区域触发取消弹窗时触发的事件。

+
+ + +dialog支持如下方法: + + + + + + + + + + + + + + + + + +

名称

+

参数

+

描述

+

show

+

-

+

弹出对话框

+

close

+

-

+

关闭对话框

+
+ + +我们已经在之前的步骤中给button分别绑定了click事件,下面我们将实现这些事件调用的方法,在index.js中添加如下代码: + +``` +import app from '@system.app'; + +import featureAbility from '@ohos.ability.featureAbility'; +import RemoteDeviceModel from '../../../model/RemoteDeviceModel.js'; + +let DEVICE_LIST_LOCALHOST; + +export default { + data: { + // 设备集合 + deviceList: [], + // 设备类对象 + remoteDeviceModel: new RemoteDeviceModel() + }, + // 初始化方法 + onInit() { + console.info('onInit begin'); + DEVICE_LIST_LOCALHOST = { + name: this.$t('strings.localhost'), + id: 'localhost' + }; + this.deviceList = [DEVICE_LIST_LOCALHOST]; + console.info('onInit end'); + }, + // 注册设备,查询设备列表 + onContinueAbilityClick() { + console.info('onContinueAbilityClick begin'); + const self = this; + this.remoteDeviceModel.registerDeviceListCallback(() => { + console.info('registerDeviceListCallback, callback entered'); + const list = []; + list[0] = DEVICE_LIST_LOCALHOST; + let deviceList; + if (self.remoteDeviceModel.discoverList.length > 0) { + deviceList = self.remoteDeviceModel.discoverList; + } else { + deviceList = self.remoteDeviceModel.deviceList; + } + console.info('on remote device updated, count=' + deviceList.length); + for (let i = 0; i < deviceList.length; i++) { + console.info('device ' + i + '/' + deviceList.length + ' deviceId=' + + deviceList[i].deviceId + ' deviceName=' + deviceList[i].deviceName + ' deviceType=' + + deviceList[i].deviceType); + list[i + 1] = { + name: deviceList[i].deviceName, + id: deviceList[i].deviceId + }; + } + self.deviceList = list; + }); + this.$element('continueAbilityDialog').show(); + console.info('onContinueAbilityClick end'); + }, + // 流转方法 + startAbilityContinuation(deviceId, deviceName) { + this.$element('continueAbilityDialog').close(); + console.info('featureAbility.startAbility deviceId=' + deviceId + + ' deviceName=' + deviceName); + const wantValue = { + bundleName: 'com.huawei.cookbook', + abilityName: 'com.huawei.cookbook.MainAbility', + deviceId: deviceId + }; + + featureAbility.startAbility({ + want: wantValue + }).then((data) => { + console.info('featureAbility.startAbility finished, ' + JSON.stringify(data)); + }); + console.info('featureAbility.startAbility want=' + JSON.stringify(wantValue)); + console.info('featureAbility.startAbility end'); + }, + // 选择设备改变的方法 + onRadioChange(inputValue, e) { + console.info('onRadioChange ' + inputValue + ', ' + e.value); + if (inputValue === e.value) { + if (e.value === 'localhost') { + this.$element('continueAbilityDialog').close(); + return; + } + if (this.remoteDeviceModel.discoverList.length > 0) { + console.info('continue to unauthed device'); + let name = null; + for (let i = 0; i < this.remoteDeviceModel.discoverList.length; i++) { + if (this.remoteDeviceModel.discoverList[i].deviceId === e.value) { + name = this.remoteDeviceModel.discoverList[i].deviceName; + break; + } + } + if (name === null) { + console.error('onRadioChange failed, can not get name from discoverList'); + return; + } + console.info('onRadioChange name=' + name); + + const self = this; + this.remoteDeviceModel.authDevice(e.value, () => { + console.info('auth and online finished'); + for (let i = 0; i < self.remoteDeviceModel.deviceList.length; i++) { + if (self.remoteDeviceModel.deviceList[i].deviceName === name) { + this.startAbilityContinuation(self.remoteDeviceModel.deviceList[i].deviceId, self.remoteDeviceModel.deviceList[i].deviceName); + } + } + }); + } else { + console.info('continue to authed device'); + for (let i = 0; i < this.remoteDeviceModel.deviceList.length; i++) { + if (this.remoteDeviceModel.deviceList[i].deviceId === e.value) { + this.startAbilityContinuation(this.remoteDeviceModel.deviceList[i].deviceId, this.remoteDeviceModel.deviceList[i].deviceName); + } + } + } + } + }, + // 销毁设备列表 + onDestroy() { + console.info('onDestroy begin'); + this.remoteDeviceModel.unregisterDeviceListCallback(); + console.info('onDestroy end'); + }, + // 隐藏设备列表对话框 + cancelDialog() { + this.remoteDeviceModel.unregisterDeviceListCallback(); + }, + // 取消设备列表 + onDismissDialogClicked() { + this.dismissDialog(); + }, + // 设备列表对话框隐藏,取消设备注册 + dismissDialog() { + this.$element('continueAbilityDialog').close(); + this.remoteDeviceModel.unregisterDeviceListCallback(); + }, + // 触控移动 + touchMove(e) { + if (e.direction === 'right') { + this.appExit(); + } + }, + // 退出应用 + appExit() { + app.terminate(); + } +}; +``` + +# 9.恭喜你 + +在本篇Codelab中,我们主要学习了OpenHarmony分布式调度启动远程FA的实现。希望通过本教程,各位开发者可以对OpenHarmony的分布式能力有一个深刻的理解。 + +# 10.参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/Distributed/RemoteStartFA) \ No newline at end of file diff --git a/Distributed/RemoteStartFA/build.gradle b/Distributed/RemoteStartFA/build.gradle index 65c90323f5b81b1f7427d57785e9121d2e598537..afa8bc4f9dd8a865ef0926d113a8546a6d796bf5 100644 --- a/Distributed/RemoteStartFA/build.gradle +++ b/Distributed/RemoteStartFA/build.gradle @@ -3,9 +3,9 @@ apply plugin: 'com.huawei.ohos.app' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 defaultConfig { - compatibleSdkVersion 6 + compatibleSdkVersion 7 } } @@ -19,7 +19,7 @@ buildscript { } } dependencies { - classpath 'com.huawei.ohos:hap:2.4.5.0' + classpath 'com.huawei.ohos:hap:3.0.1.4' classpath 'com.huawei.ohos:decctest:1.2.4.1' } } diff --git a/Distributed/RemoteStartFA/entry/src/main/js/default/pages/index/index.hml b/Distributed/RemoteStartFA/entry/src/main/js/default/pages/index/index.hml index f0e3501ca82019b6f9005ab82e326429532ff142..2b272ae372c47399c5532994c2359b0f31581c4d 100644 --- a/Distributed/RemoteStartFA/entry/src/main/js/default/pages/index/index.hml +++ b/Distributed/RemoteStartFA/entry/src/main/js/default/pages/index/index.hml @@ -19,11 +19,13 @@ 选择设备 - - +
+ + +
diff --git a/Distributed/RemoteStartFA/entry/src/main/js/default/pages/index/index.js b/Distributed/RemoteStartFA/entry/src/main/js/default/pages/index/index.js index f105a4da23dd2b3bc5fe3900134b212b6a7ff983..107957d3a52715e74f4ae623e02d36b6429a389e 100644 --- a/Distributed/RemoteStartFA/entry/src/main/js/default/pages/index/index.js +++ b/Distributed/RemoteStartFA/entry/src/main/js/default/pages/index/index.js @@ -21,7 +21,6 @@ let DEVICE_LIST_LOCALHOST; export default { data: { - title: '', deviceList: [], remoteDeviceModel: new RemoteDeviceModel() }, diff --git a/Distributed/RemoteStartFA/figures/IMG_20211213_103011.jpg b/Distributed/RemoteStartFA/figures/IMG_20211213_103011.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5c162aaab1e9421bc1b7d2571728a840b85897d Binary files /dev/null and b/Distributed/RemoteStartFA/figures/IMG_20211213_103011.jpg differ diff --git a/Distributed/RemoteStartFA/figures/IMG_20211217_144057.jpg b/Distributed/RemoteStartFA/figures/IMG_20211217_144057.jpg new file mode 100644 index 0000000000000000000000000000000000000000..157e7be6e99ec8de3693331d74adae9b057298e5 Binary files /dev/null and b/Distributed/RemoteStartFA/figures/IMG_20211217_144057.jpg differ diff --git a/Distributed/RemoteStartFA/figures/VID_20211214_114528-00_00_00-00_00_30.gif b/Distributed/RemoteStartFA/figures/VID_20211214_114528-00_00_00-00_00_30.gif new file mode 100644 index 0000000000000000000000000000000000000000..0f9ce061121609c731662f63814f153eced9182a Binary files /dev/null and b/Distributed/RemoteStartFA/figures/VID_20211214_114528-00_00_00-00_00_30.gif differ diff --git a/Distributed/RemoteStartFA/figures/pin.png b/Distributed/RemoteStartFA/figures/pin.png new file mode 100644 index 0000000000000000000000000000000000000000..06badab0e9ffd8c87cc82e9f448f351a0d6f5bae Binary files /dev/null and b/Distributed/RemoteStartFA/figures/pin.png differ diff --git "a/Distributed/RemoteStartFA/figures/\344\277\241.png" "b/Distributed/RemoteStartFA/figures/\344\277\241.png" new file mode 100644 index 0000000000000000000000000000000000000000..49074a428c2308a29171362bf46171d80c8927f0 Binary files /dev/null and "b/Distributed/RemoteStartFA/figures/\344\277\241.png" differ diff --git "a/Distributed/RemoteStartFA/figures/\345\217\226\347\211\210\346\234\254.png" "b/Distributed/RemoteStartFA/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/Distributed/RemoteStartFA/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/Distributed/RemoteStartFA/figures/\346\210\252\345\233\276.png" "b/Distributed/RemoteStartFA/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/Distributed/RemoteStartFA/figures/\346\210\252\345\233\276.png" differ diff --git "a/Distributed/RemoteStartFA/figures/\347\241\256\350\256\244.png" "b/Distributed/RemoteStartFA/figures/\347\241\256\350\256\244.png" new file mode 100644 index 0000000000000000000000000000000000000000..4e8a02292e7dfdc20865a8befb3e23ecf0053222 Binary files /dev/null and "b/Distributed/RemoteStartFA/figures/\347\241\256\350\256\244.png" differ diff --git "a/Distributed/RemoteStartFA/figures/\350\277\234\347\250\213.png" "b/Distributed/RemoteStartFA/figures/\350\277\234\347\250\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..d899c4e1ff245d9c8cb50a0f847b15f8fb3b64c7 Binary files /dev/null and "b/Distributed/RemoteStartFA/figures/\350\277\234\347\250\213.png" differ diff --git "a/Distributed/RemoteStartFA/figures/\351\237\263\344\271\220.png" "b/Distributed/RemoteStartFA/figures/\351\237\263\344\271\220.png" new file mode 100644 index 0000000000000000000000000000000000000000..a473a3a4a39363f60b6b36cdd930b23aeeab9445 Binary files /dev/null and "b/Distributed/RemoteStartFA/figures/\351\237\263\344\271\220.png" differ diff --git a/Distributed/RemoteStartFA/public_sys-resources/icon-caution.gif b/Distributed/RemoteStartFA/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Distributed/RemoteStartFA/public_sys-resources/icon-caution.gif differ diff --git a/Distributed/RemoteStartFA/public_sys-resources/icon-danger.gif b/Distributed/RemoteStartFA/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Distributed/RemoteStartFA/public_sys-resources/icon-danger.gif differ diff --git a/Distributed/RemoteStartFA/public_sys-resources/icon-note.gif b/Distributed/RemoteStartFA/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/Distributed/RemoteStartFA/public_sys-resources/icon-note.gif differ diff --git a/Distributed/RemoteStartFA/public_sys-resources/icon-notice.gif b/Distributed/RemoteStartFA/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/Distributed/RemoteStartFA/public_sys-resources/icon-notice.gif differ diff --git a/Distributed/RemoteStartFA/public_sys-resources/icon-tip.gif b/Distributed/RemoteStartFA/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/Distributed/RemoteStartFA/public_sys-resources/icon-tip.gif differ diff --git a/Distributed/RemoteStartFA/public_sys-resources/icon-warning.gif b/Distributed/RemoteStartFA/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Distributed/RemoteStartFA/public_sys-resources/icon-warning.gif differ diff --git a/ETSUI/CustomDialogEts/README.md b/ETSUI/CustomDialogEts/README.md index 1c63f9e365e16aa3796f8e4aba734af91ce273e6..f992d9e8af52bdef842d962ca2cce52d519b1fba 100644 --- a/ETSUI/CustomDialogEts/README.md +++ b/ETSUI/CustomDialogEts/README.md @@ -1,4 +1,235 @@ -# CustomDialogEts -简介 -• 此demo是用于展示基于eTS全局UI的警告弹窗与自定义弹窗的实现。 +# 1.介绍 +本文档将介绍警告弹窗、自定义弹窗的实现。效果图如下: + +**图 1** 主页效果 + + +![](figures/IMG_20211214_194906.jpg) + +**图 2** 弹窗效果 + + +![](figures/IMG_20211214_194929.jpg)![](figures/IMG_20211214_194949.jpg)![](figures/IMG_20211214_195001.jpg) + +# 2.相关概念 + +1.[Button组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-button.md) + +2.[警告弹窗](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-button.md) + +3.[自定义弹窗](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-methods-custom-dialog-box.md) + +# 3.搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 4.添加按钮Button组件 + +在这个任务中,我们需要设置Flex布局、并添加Button组件。 + +1.Flex页面布局 + +``` +@Entry +@Component +struct Index { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + } + .width('100%') + .height('100%') + } +} +``` + +2.添加Button组件 + +``` +@Entry +@Component +struct Index { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Button('one button dialog') + .backgroundColor(0x317aff) + .width(300) + Button('two button dialog') + .backgroundColor(0x317aff) + .margin({ top: 60 }).width(300) + Button('Customization dialog') + .backgroundColor(0x317aff) + .margin({ top: 60 }).width(300) + } + .width('100%') + .height('100%') + } +} +``` + +# 5.添加点击弹窗事件 + +在这个任务中,我们要分别完成包含单个按钮、两个按钮的弹窗效果设计并为分别为其绑定按钮点击事件。 + +1.包含单个按钮的弹窗效果实现 + +![](figures/IMG_20211214_194929-0.jpg) + +``` + Button('one button dialog').onClick(() => { + AlertDialog.show( + { + title: 'title', + message: 'text', + confirm: { + value: 'button', + action: () => { + console.info('Button-clicking callback') + } + }, + cancel: () => { + console.info('Closed callbacks') + } + } + ) +}).backgroundColor(0x317aff) +.width(300) +``` + +2.包含两个按钮的弹窗效果实现 + +![](figures/IMG_20211214_194949-1.jpg) + +``` +Button('two button dialog').onClick(() => { + AlertDialog.show( + { + title: 'title', + message: 'text', + primaryButton: { + value: 'cancel', + action: () => { + console.info('Callback when the first button is clicked') + } + }, + secondaryButton: { + value: 'ok', + action: () => { + console.info('Callback when the second button is clicked') + } + }, + cancel: () => { + console.info('Closed callbacks') + } + } + ) +}).backgroundColor(0x317aff) +.margin({ top: 60 }).width(300) +``` + +# 6.自定义弹窗效果实现 + +在这个任务中,我们要完成自定义内容的弹窗界面设计、并绑定相应的事件去打开或者关闭自定义弹窗。 + +![](figures/IMG_20211214_195001-2.jpg) + +1.自定义内容的弹窗界面设计,并绑定关闭弹窗的点击事件。 + +- 通过CustomDialogController类显示自定义弹窗 + +``` +@CustomDialog +struct CustomDialogExample { + controller: CustomDialogController + cancel: () => void + confirm: () => void + + build() { + Column() { + Text('Software uninstall').width('70%').fontSize(20).margin({ top: 10, bottom: 10 }) + Image($r('app.media.icon')).width(80).height(80) + Text('Whether to uninstall a software?').fontSize(16).margin({ bottom: 10 }) + Flex({ justifyContent: FlexAlign.SpaceAround }) { + Button('cancel') + .onClick(() => { + this.controller.close() + this.cancel() + }).backgroundColor(0xffffff).fontColor(Color.Black) + Button('confirm') + .onClick(() => { + this.controller.close() + this.confirm() + }).backgroundColor(0xffffff).fontColor(Color.Red) + }.margin({ bottom: 10 }) + } + } +} +``` + +2.引入自定义弹窗组件,并设置打开自定义弹窗的事件。 + +- 引入自定义弹窗组件 + +``` +@Entry +@Component +struct Index { + dialogController: CustomDialogController = new CustomDialogController({ + builder: CustomDialogExample({ cancel: this.onCancel, confirm: this.onAccept }), + cancel: this.existApp, + autoCancel: true + }) + onCancel() { + console.info('Callback when the first button is clicked') + } + onAccept() { + console.info('Callback when the second button is clicked') + } + existApp() { + console.info('Click the callback in the blank area') + } +} + +``` + +- 设置打开自定义弹窗的事件 + +``` +Button('Customization dialog').onClick(() => { + this.dialogController.open() +}).backgroundColor(0x317aff) +.margin({ top: 60 }).width(300) +``` + +# 7.恭喜你 + +- AlertDialog可以实现警告弹窗效果。 +- 可以通过CustomDialogController类显示自定义弹窗。 + +# 8.参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/CustomDialogEts) \ No newline at end of file diff --git a/ETSUI/CustomDialogEts/figures/IMG_20211214_194906.jpg b/ETSUI/CustomDialogEts/figures/IMG_20211214_194906.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2d795b081ded619defe7dadd8160d9fc22dc73be Binary files /dev/null and b/ETSUI/CustomDialogEts/figures/IMG_20211214_194906.jpg differ diff --git a/ETSUI/CustomDialogEts/figures/IMG_20211214_194929-0.jpg b/ETSUI/CustomDialogEts/figures/IMG_20211214_194929-0.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8ab3ae8ff5e14e618456c453bd697c6b383ddb5a Binary files /dev/null and b/ETSUI/CustomDialogEts/figures/IMG_20211214_194929-0.jpg differ diff --git a/ETSUI/CustomDialogEts/figures/IMG_20211214_194929.jpg b/ETSUI/CustomDialogEts/figures/IMG_20211214_194929.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8ab3ae8ff5e14e618456c453bd697c6b383ddb5a Binary files /dev/null and b/ETSUI/CustomDialogEts/figures/IMG_20211214_194929.jpg differ diff --git a/ETSUI/CustomDialogEts/figures/IMG_20211214_194949-1.jpg b/ETSUI/CustomDialogEts/figures/IMG_20211214_194949-1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6f2911125290f1e56346d92e916f5f6e9f018320 Binary files /dev/null and b/ETSUI/CustomDialogEts/figures/IMG_20211214_194949-1.jpg differ diff --git a/ETSUI/CustomDialogEts/figures/IMG_20211214_194949.jpg b/ETSUI/CustomDialogEts/figures/IMG_20211214_194949.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6f2911125290f1e56346d92e916f5f6e9f018320 Binary files /dev/null and b/ETSUI/CustomDialogEts/figures/IMG_20211214_194949.jpg differ diff --git a/ETSUI/CustomDialogEts/figures/IMG_20211214_195001-2.jpg b/ETSUI/CustomDialogEts/figures/IMG_20211214_195001-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e2f586d9cb1b0ca7a75a5314bc07e27579fd4bbd Binary files /dev/null and b/ETSUI/CustomDialogEts/figures/IMG_20211214_195001-2.jpg differ diff --git a/ETSUI/CustomDialogEts/figures/IMG_20211214_195001.jpg b/ETSUI/CustomDialogEts/figures/IMG_20211214_195001.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e2f586d9cb1b0ca7a75a5314bc07e27579fd4bbd Binary files /dev/null and b/ETSUI/CustomDialogEts/figures/IMG_20211214_195001.jpg differ diff --git "a/ETSUI/CustomDialogEts/figures/\345\217\226\347\211\210\346\234\254.png" "b/ETSUI/CustomDialogEts/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/ETSUI/CustomDialogEts/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/ETSUI/CustomDialogEts/figures/\346\210\252\345\233\276.png" "b/ETSUI/CustomDialogEts/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/ETSUI/CustomDialogEts/figures/\346\210\252\345\233\276.png" differ diff --git a/ETSUI/CustomDialogEts/public_sys-resources/icon-caution.gif b/ETSUI/CustomDialogEts/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/CustomDialogEts/public_sys-resources/icon-caution.gif differ diff --git a/ETSUI/CustomDialogEts/public_sys-resources/icon-danger.gif b/ETSUI/CustomDialogEts/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/CustomDialogEts/public_sys-resources/icon-danger.gif differ diff --git a/ETSUI/CustomDialogEts/public_sys-resources/icon-note.gif b/ETSUI/CustomDialogEts/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/ETSUI/CustomDialogEts/public_sys-resources/icon-note.gif differ diff --git a/ETSUI/CustomDialogEts/public_sys-resources/icon-notice.gif b/ETSUI/CustomDialogEts/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/ETSUI/CustomDialogEts/public_sys-resources/icon-notice.gif differ diff --git a/ETSUI/CustomDialogEts/public_sys-resources/icon-tip.gif b/ETSUI/CustomDialogEts/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/ETSUI/CustomDialogEts/public_sys-resources/icon-tip.gif differ diff --git a/ETSUI/CustomDialogEts/public_sys-resources/icon-warning.gif b/ETSUI/CustomDialogEts/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/CustomDialogEts/public_sys-resources/icon-warning.gif differ diff --git a/ETSUI/FlowLayoutEts/README.md b/ETSUI/FlowLayoutEts/README.md index fdc6116354dfc195ea6c398cf634622e94e4dc65..bd5c23f26f4a90e8471eac063ef7687adc61f39f 100644 --- a/ETSUI/FlowLayoutEts/README.md +++ b/ETSUI/FlowLayoutEts/README.md @@ -1,4 +1,311 @@ -# FlowLayoutEts -简介 -• 此demo是展示基于eTS的流式布局是如何实现的。 +# 1.介绍 + +本文档将介绍如何使用eTS实现流式布局。流式布局的特点是页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。效果图如下: + +![](figures/IMG_20211206_150939.jpg) + +## 应用场景 + +历史搜索记录、热点话题等布局效果的展示。 + +# 2.相关概念 + +TextInput:提供单行文本输入组件。 + +# 3.搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 4.编写输入框布局 + +1. 在index.ets文件中: + + - 使用@Component新增一个自定义组件,组件名为Search\_Input; + - 在build\(\)中使用Flex作为容器,实现子组件水平排列; + - 使用TextInput组件作为输入框,Button组件作为搜索按钮,内置Text组件,用来显示文本。 + + 代码如下: + + ``` + @Component + struct Search_Input { + build() { + Flex(){ + TextInput() + Button(){ + Text() + } + } + } + } + ``` + +2. 实现TextInput组件的样式及输入功能: + + - 使用@State定义变量historyInput,存储输入框的内容; + - TextInput组件参数中,将变量historyInput赋值给参数text,参数placeholder填写提示内容; + - 设置高度height、圆角borderRadius、背景颜色backgroundColor、提示内容颜色placeholderColor等方法; + - 设置TextInput组件在Flex容器的比重layoutWeight\(8\); + - 设置onChange事件,绑定用户输入的内容到变量historyInput中。 + + 代码如下: + + ``` + @Component + struct Search_Input { + @State historyInput: string = '' + + build() { + Flex(){ + TextInput({ placeholder: '请输入...', text: this.historyInput }) + .type(InputType.Normal) + .placeholderColor(Color.Red) + .placeholderFont({ size: 30, weight: 2}) + .enterKeyType(EnterKeyType.Search) + .caretColor(Color.Green) + .layoutWeight(8) + .height(40) + .borderRadius('20px') + .backgroundColor(Color.White) + .onChange((value: string) => { + this.historyInput = value + }) + } + } + } + ``` + +3. 实现Button组件的样式: + + - 设置Text组件的内容及文字大小fontSize、颜色fontColor; + - 设置Button组件在Flex容器的比重layoutWeight\(2\)。 + + 代码如下: + + ``` + @Component + struct Search_Input { + build() { + Flex({ alignItems: ItemAlign.Center }) { + Button({type: ButtonType.Capsule, stateEffect: false}) { + Text('搜索').fontSize(17).fontColor(Color.Blue) + } + .layoutWeight(2) + .backgroundColor('#00000000') + } + } + } + ``` + +4. 实现容器Flex的布局样式: + + - 设置Flex布局为水平方向ItemAlign.Center; + - 设置Flex布局的高度height、内边距padding、背景颜色backgroundColor。 + + 代码如下: + + ``` + build() { + Flex({ alignItems: ItemAlign.Center }) { + } + .height(60) + .width('100%') + .padding({left: 10}) + .backgroundColor('#FFedf2f5') + } + ``` + +5. 在@Entry修饰的主入口Search\_FlowLayout组件中,引用Search\_Input组件。代码如下: + + ``` + @Entry + @Component + struct Search_FlowLayout { + build() { + Column() { + Search_Input() + } + .height('100%') + .width('100%') + .alignItems(HorizontalAlign.Center) + } + } + ``` + +# 5.编写流式布局 + +1. 在index.ets文件中: + + - 使用@Component新增一个自定义组件,组件名为Flowlayout\_Container; + - 在build\(\)中使用Flex作为容器,设置参数wrap为FlexWrap.Wrap; + - 设置Flex容器的外边距margin和内边距padding; + - 使用@Link定义数组变量historyArr,表示子组件要显示的文本内容。 + + 代码如下: + + ``` + @Component + struct Flowlayout_Container { + @Link historyArr: string[] + + build() { + Scroll() { + Flex({justifyContent: FlexAlign.Start, wrap: FlexWrap.Wrap}) { + + } + .margin({ left: 20, bottom: 100, right: 10 }) + .padding({bottom: 10}) + } + } + } + ``` + +2. 实现流式布局效果: + + - 在Flex容器中,使用ForEach遍历变量historyArr; + - 使用Text组件作为Flex的子组件; + - 设置组件Text的文本内容为$\{item\}; + - 设置组件Text的边框宽度borderWidth、边框颜色borderColor、边框圆角borderRadius; + - 设置组件Text的外边距margin和内边距padding。 + + 代码如下: + + ``` + Flex({justifyContent: FlexAlign.Start, wrap: FlexWrap.Wrap}) { + if (this.historyArr.length > 0) { + ForEach(this.historyArr, + (item: string) => { + Text(`${item}`) + .fontSize(18) + .borderStyle(BorderStyle.Solid) + .borderWidth('1px') + .borderColor('#dddddd') + .borderRadius('90px') + .padding({top: 4, bottom: 4, right: 10, left: 10}) + .margin({top: 10, right: 10}) + .textOverflow({overflow: TextOverflow.Ellipsis}) + .maxLines(2) + }, + (item: string) => item.toString() + ) + } + } + ``` + +3. 在@Entry修饰的主入口Search\_FlowLayout组件中,引用Flowlayout\_Container组件。 + + - @State定义数组变量historyArr,用来存放文本内容。 + - 添加子组件Flowlayout\_Container。 + - 在构造参数中,使用$符号引用@State修饰的变量historyArr,将父组件的变量historyArr与子组件historyArr变量关联起来。 + + 代码如下: + + ``` + @Entry + @Component + struct Search_FlowLayout { + @State historyArr: string[] = ["Text", "Button", "TextField", "Image", "Switch", "Checkbox", "RadioButton", "ProgressBar", "ScrollView"] + + build() { + Column() { + Search_Input() + Flowlayout_Container({historyArr: $historyArr}) + } + .height('100%') + .width('100%') + .alignItems(HorizontalAlign.Center) + } + } + ``` + +# 6.添加数据 + +在本篇Codelab中,我们需要在输入框输入内容,并点击搜索按钮,将输入数据填充到流式布局中。 + +1. 在Search\_Input组件中: + + - 使用@Link定义一个数组变量historyArr; + - 定义Button组件的点击事件onClick; + - 在点击事件中,将变量historyInput的值,通过数组的unshift\(\)方法,存放在数组historyArr中。 + + 代码如下: + + ``` + @Component + struct Search_Input { + @Link historyArr: string[] + + build() { + Flex({ alignItems: ItemAlign.Center }) { + Button({type: ButtonType.Capsule, stateEffect: false}) { + } + .onClick((event: ClickEvent) => { + if (this.historyInput != null && this.historyInput.length > 0) { + this.historyArr.unshift(this.historyInput) + this.historyInput = '' + } + }) + } + } + } + ``` + +2. 在主入口Search\_FlowLayout组件中,使用$符号将父组件的变量historyArr与子组件Search\_Input的historyArr变量关联起来。代码如下: + + ``` + @Entry + @Component + struct Search_FlowLayout { + build() { + Column() { + Search_Input({historyArr: $historyArr}) + Flowlayout_Container({historyArr: $historyArr}) + } + } + } + ``` + +# 7.回顾和总结 + +- 实现ETS流式布局的核心点是设置Flex组件的参数wrap为FlexWrap.Wrap,它会实现自动换行功能。 +- 获取TextInput组件的值,需要使用一个变量存储,然后使用onChange事件获取到文本的变化。 + +- 使用数组的push\(\)、unshift\(\)方法来添加数据,不同的是push\(\)方法是在尾部添加数据,而unshift\(\)方法是在头部添加数据。 + +# 8.恭喜你 + +目前你已经成功完成了Codelab并且学到了: + +- 如何将一个ETS项目部署到OpenHarmony设备上 +- TextInput组件的使用 +- button组件的使用 +- text组件的使用 + +# 9.参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/FlowLayoutEts) diff --git a/ETSUI/FlowLayoutEts/entry/src/main/ets/MainAbility/pages/index.ets b/ETSUI/FlowLayoutEts/entry/src/main/ets/MainAbility/pages/index.ets index 788e6fbb176be50fe0e74268ce8ab5cdb5c67472..6f5b844c02bfb54088dd514ebcacfe9a83bac2f8 100644 --- a/ETSUI/FlowLayoutEts/entry/src/main/ets/MainAbility/pages/index.ets +++ b/ETSUI/FlowLayoutEts/entry/src/main/ets/MainAbility/pages/index.ets @@ -24,7 +24,7 @@ struct Search_Input { TextInput({ placeholder: '请输入...', text: this.historyInput }) .type(InputType.Normal) .placeholderColor(Color.Red) - .placeholderFont({ size: 50, weight: 2 }) + .placeholderFont({ size: 30, weight: 2 }) .enterKeyType(EnterKeyType.Search) .caretColor(Color.Green) .layoutWeight(8) @@ -49,7 +49,6 @@ struct Search_Input { } .height(60) .width('100%') - .borderStyle(BorderStyle.Dashed).borderWidth(5).borderColor(0xAFEEEE).borderRadius(10) .padding({ left: 10 }) .backgroundColor('#FFedf2f5') } diff --git a/ETSUI/FlowLayoutEts/figures/IMG_20211206_150939.jpg b/ETSUI/FlowLayoutEts/figures/IMG_20211206_150939.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4c533215bf9240bbc48a9d8335f8e40ce6b1459a Binary files /dev/null and b/ETSUI/FlowLayoutEts/figures/IMG_20211206_150939.jpg differ diff --git "a/ETSUI/FlowLayoutEts/figures/\345\217\226\347\211\210\346\234\254.png" "b/ETSUI/FlowLayoutEts/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/ETSUI/FlowLayoutEts/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/ETSUI/FlowLayoutEts/figures/\346\210\252\345\233\276.png" "b/ETSUI/FlowLayoutEts/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/ETSUI/FlowLayoutEts/figures/\346\210\252\345\233\276.png" differ diff --git a/ETSUI/FlowLayoutEts/public_sys-resources/icon-caution.gif b/ETSUI/FlowLayoutEts/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/FlowLayoutEts/public_sys-resources/icon-caution.gif differ diff --git a/ETSUI/FlowLayoutEts/public_sys-resources/icon-danger.gif b/ETSUI/FlowLayoutEts/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/FlowLayoutEts/public_sys-resources/icon-danger.gif differ diff --git a/ETSUI/FlowLayoutEts/public_sys-resources/icon-note.gif b/ETSUI/FlowLayoutEts/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/ETSUI/FlowLayoutEts/public_sys-resources/icon-note.gif differ diff --git a/ETSUI/FlowLayoutEts/public_sys-resources/icon-notice.gif b/ETSUI/FlowLayoutEts/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/ETSUI/FlowLayoutEts/public_sys-resources/icon-notice.gif differ diff --git a/ETSUI/FlowLayoutEts/public_sys-resources/icon-tip.gif b/ETSUI/FlowLayoutEts/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/ETSUI/FlowLayoutEts/public_sys-resources/icon-tip.gif differ diff --git a/ETSUI/FlowLayoutEts/public_sys-resources/icon-warning.gif b/ETSUI/FlowLayoutEts/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/FlowLayoutEts/public_sys-resources/icon-warning.gif differ diff --git a/ETSUI/MultiDeploymentEts/LICENSE b/ETSUI/MultiDeploymentEts/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..80576ef141485b36eea4aebf25af97020bc2de44 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + + 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/README.md b/ETSUI/MultiDeploymentEts/README.md index 1586e959ede664d5e6d51c66ca6e914593515558..5a35fbfcbe7b5acc5652e27a7704642fcd6b1a32 100644 --- a/ETSUI/MultiDeploymentEts/README.md +++ b/ETSUI/MultiDeploymentEts/README.md @@ -1,2 +1,331 @@ -tmp +# 一次开发多端部署 +# 介绍 + +- [应用场景](#section225718574575) + +## 应用场景 + +随着用户设备类型的不断增加,手机、平板、大屏、车载、穿戴等设备对应用UI界面开发提出了更加多样化的诉求,这就需要应用开发者在开发应用界面的时候考虑多种设备场景,从而导致工程代码量增加,甚至需要维护多个工程来适配不同设备。eTS是极简声明式UI范式开发语言,是OpenHarmony提供的一套开发能力集合,旨在帮助应用开发者快速开发UI界面,自动地适配多种不同的屏幕形态,以达到一次开发,多端部署的目的。 + +本篇Codelab使用声明式UI范式开发实现一次开发多端部署,效果预览如下: + +![](figures/VID_20211222_162936-00_00_00-00_00_30-1.gif) + +# 相关概念 + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 代码结构解读 + +本篇Codelab只对核心代码进行讲解,以下介绍整个工程的代码结构。 + +![](figures/036C0734-B95E-4D50-98E1-BEEC33160D0E.png) + +- common:自定义组件。 + - bottomTabs.ets:底部页签容器。 + - homeListItem.ets:首页推荐列表项。 + - homeTabContent.ets:首页页签内容。 + - topTabs.ets:顶部标签。 + +- model:数据结构和数据初始化。 + - homeListDataModel.ets:今日推荐、精选推荐、X月推荐数据。 + +- pages:页面。 + - home.ets:首页。 + - image.ets:图片预览界面。 + +- resources:项目资源存放路径,包括图片资源和国际化字符串等。 +- config.json:应用的配置文件。 + +# 组件的均分能力 + +底部页签使用Flex组件的均分能力,在不同的屏幕上平均分配宽度。此处使用ForEach在Flex组件中显示4个页签,每个页签是一个Column组件,四个页签会平均分配宽度。Flex组件的参数中,justifyContent参数提供均分布局能力。 + +**表 1** Flex属性方法 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数名

+

参数类型

+

必填

+

默认值

+

参数描述

+

direction

+

FlexDirection

+

+

Row

+

子组件在Flex容器上排列的方向,即主轴的方向。

+

wrap

+

FlexWrap

+

+

NoWrap

+

Flex容器是单行/列还是多行/列排列。

+

justifyContent

+

FlexAlign

+

+

Start

+

子组件在Flex容器主轴上的对齐格式。

+

alignItems

+

ItemAlign

+

+

Stretch

+

子组件在Flex容器交叉轴上的对齐格式。

+

alignContent

+

FlexAlign

+

+

Start

+

交叉轴中有额外的空间时,多行内容的对齐方式。

+
+ + +**表 2** FlexAlign: + + + + + + + + + + + + + + + + + + + + + + + + + + +

名称

+

描述

+

Start

+

元素在主轴方向首端对齐, 第一个元素与行首对齐,同时后续的元素与前一个对齐。

+

Center

+

元素在主轴方向中心对齐,第一个元素与行首的距离与最后一个元素与行尾距离相同。

+

End

+

元素在主轴方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐。

+

SpaceBetween

+

Flex主轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素与行首对齐,最后一个元素与行尾对齐。

+

SpaceAround

+

Flex主轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素到行首的距离和最后一个元素到行尾的距离时相邻元素之间距离的一半。

+

SpaceEvenly

+

Flex主轴方向元素等间距布局, 相邻元素之间的间距、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样。

+
+ + +``` +@Component +export struct BottomTabs { + build() { + // justifyContent: FlexAlign.SpaceEvenly是Flex组件的均分布局能力 + Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceEvenly }) { + ForEach(this.tabSrc, item => { + Column() { + Image(getTabSrc(this.bottomTabIndex, item)) + .objectFit(ImageFit.Contain) + .width('60%') + .height('60%') + Text($r('app.string.tab_strings')) + .fontSize(14) + .fontColor(getTabTextColor(this.bottomTabIndex, item)) + } + }) + } + .width('100%') + .height('10%') + } +} +``` + +# 组件的拉伸能力 + +本篇Codelab的首页顶部标签是自定义组件TopTabs,使用权重layoutWeight、尺寸约束、外边属性和百分比的能力来对组件进行布局约束,实现在不同设备上组件的拉伸效果。 + +layoutWeight:容器尺寸确定时,元素与兄弟节点主轴布局尺寸按照权重进行分配,忽略本身尺寸设置。 + +constraintSize:设置约束尺寸,组件布局时,进行尺寸范围限制。 + +margin:设置外边属性。 + +``` +@Component +export struct TopTabs { + build() { + Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) { + Row() { + ForEach(this.tabs, item => { + if (this.tabs.indexOf(item) == 0) { + Text(item) + .fontSize(18) + .fontWeight(FontWeight.Bold) + } else { + Text(item) + .fontSize(17) + .fontWeight(FontWeight.Medium) + .margin({ left: '5%' }) // 设置左侧距离兄弟节点的距离,使用百分比 + } + }, item => this.tabs.indexOf(item).toString()) + } + .layoutWeight(1) // 设置权重为1,其他兄弟节点不设置,则此处的文字标签会把搜索和设置图标显示后剩余的空间占满 + .height('100%') + + Image($r('app.media.search')) + .width('7%') // 占容器宽度的百分比 + .height('80%') // 占容器高度的百分比 + .constraintSize({ maxWidth: 25 }) // 尺寸约束,设置最大宽度 + .objectFit(ImageFit.Contain) + } + .height('8%') + .width('100%') + .alignSelf(ItemAlign.Start) + } +} +``` + +# 组件的占比能力 + +- 在首页中,除去底部页签和顶部标签,中间部分是可以滑动的,放在List中,List占满除去底部和顶部的空间。TabContent中,顶部显示TopTabs,List设置layoutWeight\(1\),由于顶部标签没有设置权重,所以这里List权重最高,会自动占满剩余空间。如果顶部TopTabs有设置layoutWeight,则会根据权重进行比例分配控件。。 + + layoutWeight:容器尺寸确定时,元素与兄弟节点主轴布局尺寸按照权重进行分配,忽略本身尺寸设置。 + + ``` + @Component + export struct HomeTabComponent { + build() { + Column() { + TopTabs({ showSettings: $showSettings }) + List() { + } + .listDirection(Axis.Vertical) + .width('100%') + .layoutWeight(1) + } + } + } + ``` + + +- 子组件设置占父组件固定比例。顶部Banner设置占屏幕高度的固定占比为30%,则当父组件高度不同时顶部Banner始终占父组件高度的30%。 + + ``` + @Component + export struct SubscribeSwiper { + private index: number = 0 + + build() { + Swiper() { + ForEach(subscribeItems, item => { + SwiperItem({ index: item.id }) + }, item => item.title.toString()) + } + .width('100%') + .height('30%') // 高度占父组件的30% 在不同屏幕上显示高度不同 + .indicator(false) + .index(this.index) + .autoPlay(true) + .itemSpace(15) + .displayMode(SwiperDisplayMode.AutoLinear) + .margin({ bottom: '5%' }) + } + } + ``` + +# 组件的延伸能力 + +延伸能力指布局内能够显示的组件数量根据容器组件的尺寸变化而变化,在eTS中List组件自带延伸能力,使用List组件时,在不同屏幕上显示的ListItem的数目不一样。 + +``` +List({ initialIndex: 0}) { + ForEach(this.listItems, item => { + ListItem() { + Image(item.smallImg) + .width(this.imageWidth) + .aspectRatio(this.ratio) + .borderRadius(10) + .margin({ right: 15 }) + } + }, item => item.toString()) +} +.listDirection(Axis.Horizontal) +.margin({ top: '2%', bottom: '2%' }) +``` + +# 恭喜你 + +# 参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/MultiDeploymentEts) diff --git a/ETSUI/MultiDeploymentEts/build.gradle b/ETSUI/MultiDeploymentEts/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..8091e0ece10575993ba570722aadd6788144f460 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/build.gradle @@ -0,0 +1,34 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + supportSystem "standard" +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } + dependencies { + classpath 'com.huawei.ohos:hap:3.0.3.4' + classpath 'com.huawei.ohos:decctest:1.2.6.0' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } +} diff --git a/ETSUI/MultiDeploymentEts/entry/.gitignore b/ETSUI/MultiDeploymentEts/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7d5b7a94f4dcf381f03ff21f28f8a2494b58023f --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/.gitignore @@ -0,0 +1,2 @@ +/build +/node_modules diff --git a/ETSUI/MultiDeploymentEts/entry/build.gradle b/ETSUI/MultiDeploymentEts/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..1587dd1948941f3eaaf092ae6cae7969cb6895ff --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/build.gradle @@ -0,0 +1,21 @@ +apply plugin: 'com.huawei.ohos.hap' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + defaultConfig { + compatibleSdkVersion 7 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13.1' +} diff --git a/ETSUI/MultiDeploymentEts/entry/proguard-rules.pro b/ETSUI/MultiDeploymentEts/entry/proguard-rules.pro new file mode 100644 index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/config.json b/ETSUI/MultiDeploymentEts/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..e2ac41d23f256ffa2561c9fba2df242a3d20a045 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/config.json @@ -0,0 +1,67 @@ +{ + "app": { + "bundleName": "com.example.simplegalleryetsopenh", + "vendor": "example", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "com.example.simplegalleryetsopenh", + "name": ".MyApplication", + "mainAbility": ".MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "visible": true, + "srcPath": "MainAbility", + "name": ".MainAbility", + "srcLanguage": "ets", + "icon": "$media:icon", + "description": "$string:description_mainability", + "formsEnabled": false, + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "mode": { + "syntax": "ets", + "type": "pageAbility" + }, + "pages": [ + "pages/home", + "pages/image" + ], + "name": ".MainAbility", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/app.ets b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..b7a0995c8e441cac86e21e06e7c9071664482b1c --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/app.ets @@ -0,0 +1,8 @@ +export default { + onCreate() { + console.info('Application onCreate') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/bottomTabs.ets b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/bottomTabs.ets new file mode 100644 index 0000000000000000000000000000000000000000..704d3003e158a9192e64ec28f833e6de045825ab --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/bottomTabs.ets @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 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 prompt from '@system.prompt' + +function getTabSrc(tabIndex: number, index: number) { + let imgSrc = $r('app.media.tab_gray') + if (tabIndex === index) { + imgSrc = $r('app.media.tab_blue') + } + return imgSrc +} + +function getTabTextColor(tabIndex: number, index: number) { + let color = '#000000' + if (tabIndex === index) { + color = '#0A59F7' + } + return color +} + +@Component +export struct BottomTabs { + private tabSrc: number[] = [0, 1, 2, 3] + private backgroundColor: string = '#F1F3F5' + private controller: TabsController = new TabsController() + private tips: string = '这是测试功能,暂时未实现' + @Link bottomTabIndex: number + + build() { + Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceEvenly }) { + ForEach(this.tabSrc, item => { + Column() { + Image(getTabSrc(this.bottomTabIndex, item)) + .objectFit(ImageFit.Contain) + .width('60%').height('60%') + Text($r('app.string.tab_strings')) + .fontSize(14) + .fontColor(getTabTextColor(this.bottomTabIndex, item)) + } + .onClick(() => { + if (item === this.bottomTabIndex) { + this.controller.changeIndex(this.bottomTabIndex) + } else { + prompt.showToast({ + message: this.tips + }) + } + }) + }, item => item.toString()) + } + .width('100%').height('8%') + .backgroundColor(this.backgroundColor) + } +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/homeListItem.ets b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/homeListItem.ets new file mode 100644 index 0000000000000000000000000000000000000000..167eba58f3fe127a6b0bed098687978def37c5fd --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/homeListItem.ets @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 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 router from '@system.router' +import { ImageData, initializeImageData, initializeTodayData } from '../model/homeListDataModel' + +@Component +export struct HomeListItem { + private recommends: Resource[] = [$r('app.string.today_recommend'), $r('app.string.featured_recommend'), + $r('app.string.september_recommend'), $r('app.string.august_recommend')] + private listItems: ImageData[] = initializeImageData() + private isToday: boolean = true + private titleIndex: number = 0 + private imageWidth: string = '120' + private ratio: number = 1 + + aboutToAppear() { + if (this.titleIndex === 0) { + this.listItems = initializeTodayData() + this.isToday = true + this.imageWidth = '92' + this.ratio = 1 + } else { + this.listItems = initializeImageData() + this.isToday = false + this.imageWidth = '145' + this.ratio = 0.65 + } + } + + build() { + Column() { + Row() { + Text(this.recommends[this.titleIndex]) + .textAlign(TextAlign.Start) + .fontSize(16) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + .borderColor(Color.Blue) + Text($r('app.string.more')) + .fontSize(16) + .fontColor(Color.Gray) + Image($r('app.media.more')) + .width('10').height('5%') + .alignSelf(ItemAlign.End) + .objectFit(ImageFit.Contain) + } + .width('100%') + + List({ initialIndex: 0 }) { + ForEach(this.listItems, item => { + ListItem() { + Image(item.smallImg) + .width(this.imageWidth) + .aspectRatio(this.ratio) + .borderRadius(10) + .margin({ right: 15 }) + .sharedTransition(this.titleIndex + item.id, { duration: 500, curve: Curve.Linear }) + .onClick(() => { + let shareIdStr = this.titleIndex + item.id + console.info('Item onClick' + shareIdStr) + router.push({ + uri: 'pages/image', + params: { isToday: this.isToday, shareId: shareIdStr, index: item.id, ratio: this.ratio } + }) + }) + } + }, item => item.name) + } + .listDirection(Axis.Horizontal) + .margin({ top: '2%', bottom: '2%' }) + } + } +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/homeTabContent.ets b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/homeTabContent.ets new file mode 100644 index 0000000000000000000000000000000000000000..41c9fb2df892fdc64df87ef42b8b77edb8682dfb --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/homeTabContent.ets @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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 { TopTabs } from '../common/topTabs' +import { HomeListItem } from '../common/homeListItem' + +@Component +export struct HomeTabComponent { + private recommends: Resource[] = [$r('app.string.today_recommend'), $r('app.string.featured_recommend'), + $r('app.string.september_recommend'), $r('app.string.august_recommend')] + + + build() { + Column() { + TopTabs() + List() { + ForEach(this.recommends, item => { + ListItem() { + HomeListItem({ titleIndex: this.recommends.indexOf(item) }) + } + }, item => this.recommends.indexOf(item).toString()) + } + .listDirection(Axis.Vertical) + .width('100%') + .layoutWeight(1) + } + } +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/topTabs.ets b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/topTabs.ets new file mode 100644 index 0000000000000000000000000000000000000000..b33eabf177dcb6672acbd0c950d91115f50a6a98 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/common/topTabs.ets @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 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 prompt from '@system.prompt' + +@Component +export struct TopTabs { + private tabs: Resource[] = [$r('app.string.featured'), $r('app.string.discover'), $r('app.string.wallpaper'), + $r('app.string.knowledge'), $r('app.string.photo')] + + private tips: string = '这是测试功能,暂时未实现' + + + build() { + Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) { + Row() { + ForEach(this.tabs, item => { + if (this.tabs.indexOf(item) == 0) { + Text(item) + .fontSize(18) + .fontWeight(FontWeight.Bold) + } else { + Text(item) + .fontSize(17) + .fontWeight(FontWeight.Medium) + .margin({ left: '5%' }) + } + }, item => this.tabs.indexOf(item).toString()) + } + .layoutWeight(1) + .height('100%') + + Image($r('app.media.search')) + .width('7%').height('80%') + .constraintSize({ maxWidth: 25 }) + .objectFit(ImageFit.Contain) + .onClick(() => { + prompt.showToast({ + message: this.tips + }) + }) + } + .height('8%').width('100%') + .alignSelf(ItemAlign.Start) + } +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/model/homeListDataModel.ets b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/model/homeListDataModel.ets new file mode 100644 index 0000000000000000000000000000000000000000..af19e5bdea039756f43677cc9b2e25ca64d7f139 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/model/homeListDataModel.ets @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 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 ImageData { + id: string + smallImg: Resource + bigImg: Resource + name: string + + constructor(id: string, smallImg: Resource, bigImg: Resource, name: string) { + this.id = id + this.smallImg = smallImg + this.bigImg = bigImg + this.name = name + } +} + +export function initializeImageData(): Array { + let imageDataArray: Array = [ + { "id": "0", "smallImg": $r('app.media.recommend1'), "bigImg": $r('app.media.recommend1'), "name": '推荐1' }, + { "id": "1", "smallImg": $r('app.media.recommend2'), "bigImg": $r('app.media.recommend2'), "name": '推荐2' }, + { "id": "2", "smallImg": $r('app.media.recommend3'), "bigImg": $r('app.media.recommend3'), "name": '推荐3' }, + { "id": "3", "smallImg": $r('app.media.recommend4'), "bigImg": $r('app.media.recommend4'), "name": '推荐4' }, + { "id": "4", "smallImg": $r('app.media.recommend5'), "bigImg": $r('app.media.recommend5'), "name": '推荐5' }, + { "id": "5", "smallImg": $r('app.media.recommend6'), "bigImg": $r('app.media.recommend6'), "name": '推荐6' }, + { "id": "6", "smallImg": $r('app.media.recommend7'), "bigImg": $r('app.media.recommend7'), "name": '推荐7' }, + ] + return imageDataArray +} + +export function initializeTodayData(): Array { + let todyDataArray: Array = [ + { "id": "0", "smallImg": $r('app.media.today1'), "bigImg": $r('app.media.today1'), "name": '今日推荐1' }, + { "id": "1", "smallImg": $r('app.media.today2'), "bigImg": $r('app.media.today2'), "name": '今日推荐2' }, + { "id": "2", "smallImg": $r('app.media.today3'), "bigImg": $r('app.media.today3'), "name": '今日推荐3' }, + { "id": "3", "smallImg": $r('app.media.today4'), "bigImg": $r('app.media.today4'), "name": '今日推荐4' }, + { "id": "4", "smallImg": $r('app.media.today5'), "bigImg": $r('app.media.today5'), "name": '今日推荐5' }, + { "id": "5", "smallImg": $r('app.media.today6'), "bigImg": $r('app.media.today6'), "name": '今日推荐6' }, + { "id": "6", "smallImg": $r('app.media.today7'), "bigImg": $r('app.media.today7'), "name": '今日推荐7' }, + { "id": "7", "smallImg": $r('app.media.today8'), "bigImg": $r('app.media.today8'), "name": '今日推荐8' }, + { "id": "8", "smallImg": $r('app.media.today9'), "bigImg": $r('app.media.today9'), "name": '今日推荐9' }, + { "id": "9", "smallImg": $r('app.media.today10'), "bigImg": $r('app.media.today10'), "name": '今日推荐10' }, + { "id": "10", "smallImg": $r('app.media.today11'), "bigImg": $r('app.media.today11'), "name": '今日推荐11' } + ] + return todyDataArray +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/pages/home.ets b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/pages/home.ets new file mode 100644 index 0000000000000000000000000000000000000000..96cdcdec7327daee5a3e3b60f79ecca7aa38a1c5 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/pages/home.ets @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 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 {HomeTabComponent} from '../common/homeTabContent' +import {BottomTabs} from '../common/bottomTabs' + +@Entry +@Component +struct HomeComponent { + private controller: TabsController = new TabsController() + private backgroundColor: string = '#F1F3F5' + @State bottomTabIndex: number = 0 + + build() { + Stack({ alignContent: Alignment.BottomStart }) { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.End, justifyContent: FlexAlign.End }) { + Tabs({ barPosition: BarPosition.End, index: 0, controller: this.controller }) { + TabContent() { + HomeTabComponent() + }.padding({ left: 15, right: 15 }) + + TabContent() { + } + + TabContent() { + } + + TabContent() { + } + } + .onChange((index: number) => { + this.bottomTabIndex = index + }) + .vertical(false) + .barHeight(0) + .width('100%') + .scrollable(false) + + BottomTabs({ controller: this.controller, bottomTabIndex: $bottomTabIndex }) + } + .width('100%') + .layoutWeight(1) + .backgroundColor(this.backgroundColor) + } + .width('100%').height('100%') + } +} diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/pages/image.ets b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/pages/image.ets new file mode 100644 index 0000000000000000000000000000000000000000..d49e6c678fbe16ac7ba3cf660e62426fbfcd9530 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/ets/MainAbility/pages/image.ets @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2021 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 router from '@system.router' +import {ImageData, initializeImageData, initializeTodayData} from '../model/homeListDataModel' + +@Entry +@Component +struct ImageComponent { + private imageSrc: ImageData[] = initializeImageData() + private imageIndex: number = router.getParams().index + private shareId: string = router.getParams().shareId + private isToday: boolean = router.getParams().isToday + @State ratio: number = router.getParams().ratio + @State title: string = '' + @State imageMargin: number = 56 + @State visibility: Visibility = Visibility.Visible + @State scale: number = 1 + + aboutToAppear() { + if (this.isToday) { + this.imageSrc = initializeTodayData() + } else { + this.imageSrc = initializeImageData() + } + if(this.imageIndex < this.imageSrc.length) { + this.title = this.imageSrc[this.imageIndex].name + } + + setTimeout(()=>{ + this.ratio = 0 + },500) + } + + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.End, justifyContent: FlexAlign.End }) { + Row() { + Image($r('app.media.arrow')) + .width('8%').height('50%') + .objectFit(ImageFit.Contain) + .margin({ left: 10 }) + .onClick(() => { + router.back() + }) + Text(this.title) + .fontSize(20) + .fontColor(Color.Black) + .margin({ left: 10 }) + } + .width('100%').height(this.imageMargin) + .backgroundColor('#F1F3F5') + .visibility(this.visibility) + + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Swiper() { + ForEach(this.imageSrc, item => { + Image(item.bigImg) + .height('100%').width('100%') + .objectFit(ImageFit.Contain) + .onClick(() => { + console.info('Image Click') + this.scale = 1 + if (this.visibility == Visibility.Hidden) { + this.imageMargin = 56 + this.visibility = Visibility.Visible + } else { + this.imageMargin = 0 + this.visibility = Visibility.Hidden + } + }) + .gesture( + GestureGroup(GestureMode.Parallel, + PinchGesture() + .onActionStart(() => { + console.log('pinch start') + }) + .onActionUpdate((event: GestureEvent) => { + if (this.visibility == Visibility.Hidden && event.scale <= 2.0) { + this.scale = event.scale + } + }) + .onActionEnd(() => { + if (this.scale < 1.0) { + animateTo({ duration: 500, curve: Curve.Ease }, () => { + this.scale = 1.0 + }) + } + }) + , TapGesture({ count: 2, fingers: 1 }) + .onAction(() => { + if (this.visibility == Visibility.Hidden) { + animateTo({ duration: 500, curve: Curve.Ease }, () => { + this.scale = this.scale < 2.0 ? 2.0 : 1.0 + }) + } + }) + ) + ) + }, item => item.name) + } + .width('100%').height('100%') + .aspectRatio(this.ratio) + .scale({ x: this.scale, y: this.scale }) + .index(this.imageIndex) + .indicator(false) + .loop(false) + .sharedTransition(this.shareId, { duration: 500, curve: Curve.Linear }) + .onChange((index: number) => { + this.scale = 1.0 + this.imageIndex = index + if(this.imageIndex < this.imageSrc.length) { + this.title = this.imageSrc[this.imageIndex].name + } + }) + }.width('100%').height('100%') + + Column() { + Image($r('app.media.delete')) + .objectFit(ImageFit.Contain) + .width(25).height(25) + .margin({ top: 5 }) + Text($r('app.string.delete')) + .fontSize(14) + .fontColor(Color.Black) + .textAlign(TextAlign.Start) + } + .width('100%').height(this.imageMargin) + .backgroundColor('#F1F3F5') + .visibility(this.visibility) + } + .width('100%').height('100%') + } +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/element/string.json b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..80d28f0c16810e0bce680a69448d8fe5d64801c0 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/element/string.json @@ -0,0 +1,96 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "SimpleGallery" + }, + { + "name": "mainability_description", + "value": "Simple_Gallery_Ability" + }, + { + "name": "tips", + "value": "This is a test function and has not been implemented." + }, + { + "name": "tab_strings", + "value": "Tab" + }, + { + "name": "featured", + "value": "featured" + }, + { + "name": "discover", + "value": "discover" + }, + { + "name": "wallpaper", + "value": "wallpaper" + }, + { + "name": "knowledge", + "value": "knowledge" + }, + { + "name": "photo", + "value": "photo" + }, + { + "name": "more", + "value": "more" + }, + { + "name": "delete", + "value": "delete" + }, + { + "name": "today_recommend", + "value": "Today Recommends" + }, + { + "name": "featured_recommend", + "value": "Featured Recommends" + }, + { + "name": "september_recommend", + "value": "September Recommends" + }, + { + "name": "august_recommend", + "value": "August Recommends" + }, + { + "name": "notification_settings", + "value": "Notification Settings" + }, + { + "name": "harmony_notification", + "value": "HarmonyOS Notification" + }, + { + "name": "background_reminderAgent", + "value": "HarmonyOS Background ReminderAgent" + }, + { + "name": "reminder_tips", + "value": "After the setting, the system clears the app, restarts the device, and shuts down the device. The notification is triggered normally." + }, + { + "name": "subscribe_succeed", + "value": "Subscribe succeed." + }, + { + "name": "add_reminder", + "value": "Do you want to add to the HarmonyOS background reminder?" + }, + { + "name": "yes", + "value": "Yes" + }, + { + "name": "no", + "value": "No" + } + ] +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/arrow.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..24513e54f3119d8e91d922108086afe8a5f766d3 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/arrow.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/close.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/close.png new file mode 100644 index 0000000000000000000000000000000000000000..4c7a6b6a3ade46a7754330a726fa3bd04c29f8e4 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/close.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/close_white.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/close_white.png new file mode 100644 index 0000000000000000000000000000000000000000..ec0c15ff0305c38df600447e7c2ba3d5da988b83 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/close_white.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/delete.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..8ad06f881d9e4aec1de46037679378252909548f Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/delete.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/icon.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/icon.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt1.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt1.png new file mode 100644 index 0000000000000000000000000000000000000000..408057b38163cdc5d9dc360014717e2dcc744cff Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt1.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt2.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt2.png new file mode 100644 index 0000000000000000000000000000000000000000..e136d552c3ea57088ea911d122a876819741234f Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt2.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt3.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt3.png new file mode 100644 index 0000000000000000000000000000000000000000..34690f9986b41c3f1b479d8472ffd512fcb6a927 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt3.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt4.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt4.png new file mode 100644 index 0000000000000000000000000000000000000000..edfa1afc4b5fd4a7e96e057f3b6a1b7c1f936966 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/jxdt4.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/more.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/more.png new file mode 100644 index 0000000000000000000000000000000000000000..4e361e699556a5b5ccae46dff999498baee96538 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/more.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend1.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend1.png new file mode 100644 index 0000000000000000000000000000000000000000..ebb003623e4ab60b180f54b12ced7520f62bc723 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend1.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend2.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend2.png new file mode 100644 index 0000000000000000000000000000000000000000..97f16b5fe63bd560c53988a0f6a07b8c6708e010 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend2.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend3.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend3.png new file mode 100644 index 0000000000000000000000000000000000000000..cd31df038600918012be012f520f4a0b2af47022 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend3.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend4.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend4.png new file mode 100644 index 0000000000000000000000000000000000000000..00cc73f4cc0331b59682045f4137d8f168aec8f5 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend4.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend5.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend5.png new file mode 100644 index 0000000000000000000000000000000000000000..a0fcc49852e8d6e6e9daad638884a41d94e0f3dc Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend5.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend6.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend6.png new file mode 100644 index 0000000000000000000000000000000000000000..0ca15c77deb161b1881eef9a0806ffdc45e8b7d2 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend6.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend7.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend7.png new file mode 100644 index 0000000000000000000000000000000000000000..c880ab0c9c4e009512fc521730159e5bef27d840 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/recommend7.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/search.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/search.png new file mode 100644 index 0000000000000000000000000000000000000000..68db577dc6b6e66a7e1784946175b2b5ce5499bd Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/search.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/setting.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/setting.png new file mode 100644 index 0000000000000000000000000000000000000000..5dd1d3d9d176380abdbd23afd0fe1e1dc2fe425c Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/setting.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/tab_blue.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/tab_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..c0882ba31589e41a902a0ed31075f8c55527129c Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/tab_blue.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/tab_gray.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/tab_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..32b626cf1e7da20c1cf8a45fc60727132ce0df2f Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/tab_gray.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today1.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today1.png new file mode 100644 index 0000000000000000000000000000000000000000..0ac6a72df85e065a8370ad408190109efa7865eb Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today1.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today10.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today10.png new file mode 100644 index 0000000000000000000000000000000000000000..0c63fee7fcbdce1f06eed0a11d49e83b68384a7d Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today10.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today11.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today11.png new file mode 100644 index 0000000000000000000000000000000000000000..75839f1e6626cd3623b204aa01029a6677be5589 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today11.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today2.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today2.png new file mode 100644 index 0000000000000000000000000000000000000000..f4657834613751d940341607854a3fb9dc7c19b2 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today2.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today3.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today3.png new file mode 100644 index 0000000000000000000000000000000000000000..50c2c40f5db6d726ac9a739ce4cc5894f7f3b7a4 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today3.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today4.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today4.png new file mode 100644 index 0000000000000000000000000000000000000000..363167853b7e47c81a929c2eff02dfe310488bfd Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today4.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today5.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today5.png new file mode 100644 index 0000000000000000000000000000000000000000..3b214b21626640fa4cf61fd3ec5796153d0e2e4d Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today5.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today6.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today6.png new file mode 100644 index 0000000000000000000000000000000000000000..48d48a42818b15ac3b8233ddb96c6146a8ed765d Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today6.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today7.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today7.png new file mode 100644 index 0000000000000000000000000000000000000000..759cbae649902badb8c8764769aa754ae407fd01 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today7.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today8.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today8.png new file mode 100644 index 0000000000000000000000000000000000000000..f082b0bfb20e6f7ca780609c5d6419b177bfe77c Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today8.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today9.png b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today9.png new file mode 100644 index 0000000000000000000000000000000000000000..f8d68d02c5fa6aa7c1f0c44a74d3791dd332bce4 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/entry/src/main/resources/base/media/today9.png differ diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/en/element/string.json b/ETSUI/MultiDeploymentEts/entry/src/main/resources/en/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..5857634212ce578c929519e20004371910423915 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/resources/en/element/string.json @@ -0,0 +1,96 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "SimpleGallery" + }, + { + "name": "mainability_description", + "value": "ETS_Empty Feature Ability" + }, + { + "name": "tips", + "value": "This is a test function and has not been implemented." + }, + { + "name": "tab_strings", + "value": "Tab" + }, + { + "name": "featured", + "value": "featured" + }, + { + "name": "discover", + "value": "discover" + }, + { + "name": "wallpaper", + "value": "wallpaper" + }, + { + "name": "knowledge", + "value": "knowledge" + }, + { + "name": "photo", + "value": "photo" + }, + { + "name": "more", + "value": "more" + }, + { + "name": "delete", + "value": "delete" + }, + { + "name": "today_recommend", + "value": "Today Recommends" + }, + { + "name": "featured_recommend", + "value": "Featured Recommends" + }, + { + "name": "september_recommend", + "value": "September Recommends" + }, + { + "name": "august_recommend", + "value": "August Recommends" + }, + { + "name": "notification_settings", + "value": "Notification Settings" + }, + { + "name": "harmony_notification", + "value": "HarmonyOS Notification" + }, + { + "name": "background_reminderAgent", + "value": "HarmonyOS Background ReminderAgent" + }, + { + "name": "reminder_tips", + "value": "After the setting, the system clears the app, restarts the device, and shuts down the device. The notification is triggered normally." + }, + { + "name": "subscribe_succeed", + "value": "Subscribe succeed." + }, + { + "name": "add_reminder", + "value": "Do you want to add to the HarmonyOS background reminder?" + }, + { + "name": "yes", + "value": "Yes" + }, + { + "name": "no", + "value": "No" + } + ] +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/rawfile/string.json b/ETSUI/MultiDeploymentEts/entry/src/main/resources/rawfile/string.json new file mode 100644 index 0000000000000000000000000000000000000000..0951821113958ff9f2fe8ea115edf3eb808035e7 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/resources/rawfile/string.json @@ -0,0 +1,5 @@ +{ + "strings": { + "test_tips": "这是测试功能,暂时还未实现." + } +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/entry/src/main/resources/zh/element/string.json b/ETSUI/MultiDeploymentEts/entry/src/main/resources/zh/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..042ddea66a52b629892b63e5e2b7bfd00948dd05 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/entry/src/main/resources/zh/element/string.json @@ -0,0 +1,96 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "简单图库" + }, + { + "name": "mainability_description", + "value": "简单图库能力" + }, + { + "name": "tab_strings", + "value": "页签" + }, + { + "name": "tips", + "value": "这是测试功能,暂时还未实现." + }, + { + "name": "featured", + "value": "精选" + }, + { + "name": "discover", + "value": "发现" + }, + { + "name": "wallpaper", + "value": "壁纸" + }, + { + "name": "knowledge", + "value": "知识" + }, + { + "name": "photo", + "value": "摄影" + }, + { + "name": "more", + "value": "更多" + }, + { + "name": "delete", + "value": "删除" + }, + { + "name": "today_recommend", + "value": "今日推荐" + }, + { + "name": "featured_recommend", + "value": "精选推荐" + }, + { + "name": "september_recommend", + "value": "9月推荐" + }, + { + "name": "august_recommend", + "value": "8月推荐" + }, + { + "name": "notification_settings", + "value": "通知设置" + }, + { + "name": "harmony_notification", + "value": "鸿蒙系统提醒" + }, + { + "name": "background_reminderAgent", + "value": "HarmonyOS后台代理提醒" + }, + { + "name": "reminder_tips", + "value": "设置后,清除应用、重启设备、设备关机,提醒正常触发" + }, + { + "name": "subscribe_succeed", + "value": "预定成功。" + }, + { + "name": "add_reminder", + "value": "是否添加到HarmonyOS后台代理提醒?" + }, + { + "name": "yes", + "value": "是" + }, + { + "name": "no", + "value": "否" + } + ] +} \ No newline at end of file diff --git a/ETSUI/MultiDeploymentEts/figures/036C0734-B95E-4D50-98E1-BEEC33160D0E.png b/ETSUI/MultiDeploymentEts/figures/036C0734-B95E-4D50-98E1-BEEC33160D0E.png new file mode 100644 index 0000000000000000000000000000000000000000..092e5bd3c895389454ca2d8203ccf5a5a4d832e4 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/figures/036C0734-B95E-4D50-98E1-BEEC33160D0E.png differ diff --git a/ETSUI/MultiDeploymentEts/figures/VID_20211222_162936-00_00_00-00_00_30-1.gif b/ETSUI/MultiDeploymentEts/figures/VID_20211222_162936-00_00_00-00_00_30-1.gif new file mode 100644 index 0000000000000000000000000000000000000000..d771e7630f4617e2c8581d796d3f0622d904d1f8 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/figures/VID_20211222_162936-00_00_00-00_00_30-1.gif differ diff --git "a/ETSUI/MultiDeploymentEts/figures/\345\217\226\347\211\210\346\234\254.png" "b/ETSUI/MultiDeploymentEts/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/ETSUI/MultiDeploymentEts/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/ETSUI/MultiDeploymentEts/figures/\346\210\252\345\233\276.png" "b/ETSUI/MultiDeploymentEts/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/ETSUI/MultiDeploymentEts/figures/\346\210\252\345\233\276.png" differ diff --git a/ETSUI/MultiDeploymentEts/gradle/wrapper/gradle-wrapper.jar b/ETSUI/MultiDeploymentEts/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/gradle/wrapper/gradle-wrapper.jar differ diff --git a/ETSUI/MultiDeploymentEts/gradle/wrapper/gradle-wrapper.properties b/ETSUI/MultiDeploymentEts/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..f59159e865d4b59feb1b8c44b001f62fc5d58df4 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/ETSUI/MultiDeploymentEts/public_sys-resources/icon-caution.gif b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-caution.gif differ diff --git a/ETSUI/MultiDeploymentEts/public_sys-resources/icon-danger.gif b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-danger.gif differ diff --git a/ETSUI/MultiDeploymentEts/public_sys-resources/icon-note.gif b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-note.gif differ diff --git a/ETSUI/MultiDeploymentEts/public_sys-resources/icon-notice.gif b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-notice.gif differ diff --git a/ETSUI/MultiDeploymentEts/public_sys-resources/icon-tip.gif b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-tip.gif differ diff --git a/ETSUI/MultiDeploymentEts/public_sys-resources/icon-warning.gif b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/MultiDeploymentEts/public_sys-resources/icon-warning.gif differ diff --git a/ETSUI/MultiDeploymentEts/settings.gradle b/ETSUI/MultiDeploymentEts/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07 --- /dev/null +++ b/ETSUI/MultiDeploymentEts/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/ETSUI/ShoppingEts/LICENSE b/ETSUI/ShoppingEts/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..7c357dc828cf7d8c783f10ed6bb1bac8a1e903c1 --- /dev/null +++ b/ETSUI/ShoppingEts/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2021 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/ETSUI/ShoppingEts/README.md b/ETSUI/ShoppingEts/README.md index 1586e959ede664d5e6d51c66ca6e914593515558..f76dc70f4bf207f8e864c0f56efe30e450a71568 100644 --- a/ETSUI/ShoppingEts/README.md +++ b/ETSUI/ShoppingEts/README.md @@ -1,2 +1,1231 @@ -tmp +# 概述 +OpenHarmony ArkUI框架提供了丰富的动画组件和接口,开发者可以根据实际场景和开发需求,选用丰富的动画组件和接口来实现不同的动画效果。 + +本Codelab中,我们会构建一个简易的购物应用。应用包含两级页面,分别是主页(“商品浏览”页签、“购物车”页签、“我的”页签)和商品详情页面。效果如下图所示: + +![](figures/1_zh-cn_image_0000001160725256.png) + +# 代码结构解读 + +本篇Codelab只对核心代码进行讲解,首先来介绍下整个工程的代码结构: + +![](figures/shopca.png) + +- model:存放封装好的数据实体。 + - ArsData:我的页签相关参数实体。 + - GoodsData:商品列表页商品实体。 + - GoodsDataModels:各种实体的具体数据以及获取数据的方法。 + - Menu:我的页签菜单实体。 + +- pages:存放页面。 + - HomePage:应用主页面,包含商品列表页签。 + - MyPage:我的页签。 + - ShoppingCartPage:购物车页签。 + - ShoppingDetail:商品详情页。 + +- resources :存放工程使用到的资源文件。 + - resources/base/media:存放工程中使用的图片资源。 + +- config.json:配置文件。 +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) +# 构建商品列表页签 + +在本节中,我们将完成商品列表页签的设计,效果图如下: + +![](figures/HoomPage.png) + +从效果图可以看出,商品列表页签主要由三个部分组成: + +1. 顶部的Tabs组件。 +2. 中间TabContent组件内包含List组件。其中List组件的item是一个水平布局,由一个垂直布局和一个Image组件组成;item中的垂直布局由3个Text组件组成。 +3. 底部的导航页签。 + +实现步骤如下: + +1. 在pages目录下面新建一个ETS Page,命名为HomePage.ets,在config.json文件的pages属性中会自动添加“pages/HomePage”页面路由。 + + ![](figures/新建页面.png) + + >![](public_sys-resources/icon-note.gif) **说明:** + >- 页面文件名不能使用组件名称,比如:Text.ets、Button.ets等。 + >- 每个页面文件中必须包含入口组件。 + +2. 新建与pages文件夹同级的model文件夹,并在model目录下新建ArsData.ets、GoodsData.ets、Menu.ets和GoodsDataModels.ets文件,其中ArsData.ets、GoodsData.ets、Menu.ets是数据实体类,GoodsDataModels.ets是存放这三种实体数据集合,并定义了获取各种数据集合的方法。数据实体包含实体的属性和构造方法,可通过new ArsData\(string,string\) 来获取ArsData对象,ArsData.ets内容如下: + + ``` + let NextId = 0; + export class ArsData { + id: string; + title: string; + content: string; + + constructor(title: string, content: string) { + this.id = `${NextId++}`; + this.title = title; + this.content = content; + } + } + ``` + + GoodsData.ets代码如下: + + ``` + let NextId = 0; + export class GoodsData { + id: string; + title: string; + content: string; + price: number; + imgSrc: Resource; + + constructor(title: string, content: string, price: number, imgSrc: Resource) { + this.id = `${NextId++}`; + this.title = title; + this.content = content; + this.price = price; + this.imgSrc = imgSrc; + } + } + ``` + + 一个文件中可以包含多个class ,Menu.ets中就包含了Menu类和ImageItem类,Menu.ets代码如下 + + ``` + let NextId = 0; + export class Menu { + id: string; + title: string; + num: number; + + constructor(title: string, num: number) { + this.id = `${NextId++}`; + this.title = title; + this.num = num; + } + } + + export class ImageItem { + id: string; + title: string; + imageSrc: Resource; + + constructor(title: string, imageSrc: Resource) { + this.id = `${NextId++}`; + this.title = title; + this.imageSrc = imageSrc; + } + } + + ``` + + GoodsDataModels.ets代码如下: + + ``` + import {GoodsData} from './GoodsData' + + import {Menu, ImageItem} from './Menu' + import {ArsData} from './ArsData' + //获取商品列表数据 + export function initializeOnStartup(): Array { + let GoodsDataArray: Array = [] + GoodsComposition.forEach(item => { + console.log(item.title); + GoodsDataArray.push(new GoodsData(item.title, item.content, item.price, item.imgSrc)); + }) + return GoodsDataArray; + } + //获取底部默认图片列表数据 + export function getIconPath(): Array { + let IconPath: Array = ['nav/icon-buy.png','nav/icon-shopping-cart.png','nav/icon-my.png'] + + return IconPath; + } + //获取选中后图片列表数据 + export function getIconPathSelect(): Array { + let IconPathSelect: Array = ['nav/icon-home.png','nav/icon-shopping-cart-select.png','nav/icon-my-select.png'] + + return IconPathSelect; + } + //获取商品详情页图片详情列表 + export function getDetailImages(): Array { + let detailImages: Array = ['computer/computer1.png','computer/computer2.png','computer/computer3.png','computer/computer4.png','computer/computer5.png','computer/computer6.png'] + + return detailImages; + } + + //获取菜单数据列表 + export function getMenu(): Array { + let MenuArray: Array = [] + MyMenu.forEach(item => { + MenuArray.push(new Menu(item.title,item.num)); + }) + return MenuArray; + } + //获取MyTrans数据列表 + export function getTrans(): Array { + let ImageItemArray: Array = [] + MyTrans.forEach(item => { + ImageItemArray.push(new ImageItem(item.title,item.imageSrc)); + }) + return ImageItemArray; + } + //获取More数据列表 + export function getMore(): Array { + let ImageItemArray: Array = [] + MyMore.forEach(item => { + ImageItemArray.push(new ImageItem(item.title,item.imageSrc)); + }) + return ImageItemArray; + } + //获取参数列表 + export function getArs(): Array { + let ArsItemArray: Array = [] + ArsList.forEach(item => { + ArsItemArray.push(new ArsData(item.title,item.content)); + }) + return ArsItemArray; + } + //数据集合部分 + ... + ``` + +3. 在HomePage.ets文件中创建商品列表页签相关的组件,其中GoodsHome效果图如下: + + ![](figures/1.png) + + 代码如下: + + ``` + @Component + @Component + struct GoodsHome { + private goodsItems: GoodsData[] + + build() { + Column() { + Tabs() { + TabContent() { + GoodsList({ goodsItems: this.goodsItems }); + } + .tabBar("Top Sellers") + .backgroundColor(Color.White) + + TabContent() { + GoodsList({ goodsItems: this.goodsItems }); + } + .tabBar("Recommended") + .backgroundColor(Color.White) + + TabContent() { + GoodsList({ goodsItems: this.goodsItems }); + } + .tabBar("Lifestyle") + .backgroundColor(Color.White) + + TabContent() { + GoodsList({ goodsItems: this.goodsItems }); + } + .tabBar("Deals") + .backgroundColor(Color.White) + } + .barWidth(540) + .barHeight(50) + .scrollable(true) + .barMode(BarMode.Scrollable) + .backgroundColor('#007DFF') + .height('100%') + } + .alignItems(HorizontalAlign.Start) + } + } + ``` + + 在GoodsHome中使用Tabs组件,在Tabs组件中设置4个TabContent,给每个TabContent设置tabBar属性,并设置TabContent容器中的内容GoodsList组件,GoodsList组件效果图如下: + + ![](figures/2.png) + + 代码如下: + + ``` + @Component + struct GoodsList { + private goodsItems: GoodsData[] + + build() { + Column() { + List() { + ForEach(this.goodsItems, item => { + ListItem() { + GoodsListItem({ goodsItem: item }) + } + }, item => item.id.toString()) + } + .height('100%') + .width('100%') + .align(Alignment.Top) + .margin({top: 5}) + } + } + } + ``` + + 在GoodsList组件中遍历商品数据集合,ListItem组件中设置组件内容,并使用Navigator组件给每个Item设置顶级跳转路由,GoodsListItem组件效果图如下: + + ![](figures/5.png) + + 代码如下: + + ``` + @Component + struct GoodsListItem { + private goodsItem: GoodsData + + build() { + Navigator({ target: 'pages/ShoppingDetail' }) { + Row() { + Column() { + Text(this.goodsItem.title) + .fontSize(18) + Text(this.goodsItem.content) + .fontSize(14) + Text('¥' + this.goodsItem.price) + .fontSize(18) + .fontColor(Color.Red) + } + .height(130) + .width('60%') + .margin({ left: 20 }) + .alignItems(HorizontalAlign.Start) + + Image(this.goodsItem.imgSrc) + .objectFit(ImageFit.ScaleDown) + .height(130) + .width('30%') + .renderMode(ImageRenderMode.Original) + .margin({ right: 10, left: 10 }) + + } + .backgroundColor(Color.White) + + } + .params({ goodsData: this.goodsItem }) + .margin({ right: 5 }) + } + } + ``` + +4. 在HomePage.ets中创建文件入口组件(Index)以及底部页签导航组件(HomeBottom),导入需要使用到的数据实体类以及需要使用的方法和组件,每个page文件都必须包含一个入口组件,使用@Entry修饰,HomePage文件中的入口组件(Index)代码如下: + + ``` + import {GoodsData} from '../model/GoodsData' + import {initializeOnStartup,getIconPath,getIconPathSelect} from '../model/GoodsDataModels' + import {ShoppingCart} from './ShoppingCartPage.ets' + import {MyInfo} from './MyPage.ets' + import router from '@system.router' + @Entry + @Component + struct Index { + @Provide currentPage: number = 1 + private goodsItems: GoodsData[] = initializeOnStartup() + build() { + Column() { + Scroll(){ + Column() { + if (this.currentPage == 1) { + GoodsHome({ goodsItems: this.goodsItems }) + } else if (this.currentPage == 2) { + //购物车列表 + ShoppingCart() + } else { + //我的 + MyInfo() + } + } + .width('100%') + .flexGrow(1) + } + .scrollable(ScrollDirection.Vertical) + HomeBottom() + } + .height('93%') + .width('100%') + .backgroundColor("white") + + } + } + ``` + + 从入口组件的代码中可以看出,我们定义了一个全局变量currentPage ,并且使用@provide修饰,在其子组件\(HomeBottom\)中使用@Consume修饰。当子组件currentPage发生变化的时候,父组件currentPage也会发生变化,会重新加载页面,显示不同的页签。在入口组件中,通initializeOnStartup获取商品列表数据(goodsItems)并传入GoodsHome组件中。底部组件是由一个横向的图片列表组成,iconPath是底部初始状态下的3张图片路径数组。遍历iconPath数组,使用Image组件设置图片路径并添加到List中,给每个Image组件设置点击事件,点击更换底部3张图片。在HomeBottom中,iconPath使用的是@State修饰,当iconPath数组内容变化时,页面组件有使用到的地方都会随之发生变化。HomeBottom组件效果图如下: + + ![](figures/3.png) + + 代码如下: + + ``` + @Component + struct HomeBottom { + @Consume currentPage: number + private iconPathTmp: IconImage[] = getIconPath() + private iconPathSelectsTmp: IconImage[] = getIconPathSelect() + @State iconPath: IconImage[] = getIconPath() + + build() { + Row() { + Image(this.iconPath[0].imgSrc) + .objectFit(ImageFit.Contain) + .height(120) + .width(120) + .margin({left:80,top: 20}) + .renderMode(ImageRenderMode.Original) + .onClick(()=>{ + this.iconPath[0] = this.iconPathTmp[0] + this.iconPath[1] = this.iconPathTmp[1] + this.iconPath[2] = this.iconPathTmp[2] + this.currentPage = 1 + }) + Image(this.iconPath[1].imgSrc) + .objectFit(ImageFit.Contain) + .height(120) + .width(120) + .margin({left:80,top: 20}) + .renderMode(ImageRenderMode.Original) + .onClick(()=>{ + this.iconPath[0] = this.iconPathSelectsTmp[0] + this.iconPath[1] = this.iconPathSelectsTmp[1] + this.iconPath[2] = this.iconPathTmp[2] + this.currentPage = 2 + }) + Image(this.iconPath[2].imgSrc) + .objectFit(ImageFit.Contain) + .height(120) + .width(120) + .margin({left:80,top: 20}) + .renderMode(ImageRenderMode.Original) + .onClick(()=>{ + this.iconPath[0] = this.iconPathSelectsTmp[0] + this.iconPath[1] = this.iconPathTmp[1] + this.iconPath[2] = this.iconPathSelectsTmp[2] + this.currentPage = 3 + }) + + } + .backgroundColor(Color.White) + .alignItems(VerticalAlign.Bottom) + .width('100%') + .height('10%') + } + } + ``` + + +# 构建购物车页签 + +![](figures/shopingCart2.png) + +从上面效果图可以看出,主界面购物车页签主要由下面三部分组成: + +1. 顶部的Text组件。 +2. 中间的List组件,其中List组件的item是一个水平的布局内包含一个toggle组件,一个Image组件和一个垂直布局,其item中的垂直布局是由2个Text组件组成。 +3. 底部一个水平布局包含两个Text组件。 + +在本任务中我们主要是构建一个购物车页签,给商品列表的每个商品设置一个单选框,可以选中与取消选中,底部Total值也会随之增加或减少,点击Check Out时会触发弹窗。下面我们来完成ShoppingCart页签。 + +1. 在pages目录下面新建一个ETS Page ,命名为ShoppingCart.ets,config.json文件pages属性中也会自动添加“pages/ShoppingCart”页面路由。 +2. 在ShoppingCartPage.ets文件中添加入口组件\(ShoppingCart\),并导入需要使用到的数据实体类、方法和组件。ShoppingCart组件代码如下: + + ``` + import {GoodsData} from '../model/GoodsData' + import {initializeOnStartup} from '../model/GoodsDataModels' + import prompt from '@system.prompt'; + + @Entry + @Component + export struct ShoppingCart { + @Provide totalPrice: number = 0 + private goodsItems: GoodsData[] = initializeOnStartup() + + build() { + Column() { + Column() { + Text('ShoppingCart') + .fontColor(Color.Black) + .fontSize(25) + .margin({ left: 60, right: 60 }) + .align(Alignment.Center) + } + .backgroundColor('#FF00BFFF') + .width('100%') + .height(30) + + ShopCartList({ goodsItems: this.goodsItems }); + ShopCartBottom() + } + .height('100%') + .width('100%') + .alignItems(HorizontalAlign.Start) + } + } + ``` + +3. 新建ShopCartList组件用于存放购物车商品列表,ShopCartList组件效果图如下: + + ![](figures/6.png) + + 代码如下: + + ``` + @Component + struct ShopCartList { + private goodsItems: GoodsData[] + + build() { + Column() { + List() { + ForEach(this.goodsItems, item => { + ListItem() { + ShopCartListItem({ goodsItem: item }) + } + }, item => item.id.toString()) + } + .height('100%') + .width('100%') + .align(Alignment.Top) + .margin({ top: 5 }) + } + .height('90%') + } + } + ``` + + 在ShopCartListItem中使用Toggle的单选框类型来实现每个item的选择和取消选择,在Toggle的onChage事件中来改变totalPrice的数值。ShopCartListItem组件效果图如下: + + ![](figures/8.png) + + 代码如下: + + ``` + @Component + struct ShopCartListItem { + @Consume totalPrice: number + private goodsItem: GoodsData + + build() { + Row() { + Toggle({ type: ToggleType.Checkbox }) + .width(13) + .height(13) + .onChange((isOn: boolean) => { + if (isOn) { + this.totalPrice += parseInt(this.goodsItem.price + '', 0) + } else { + this.totalPrice -= parseInt(this.goodsItem.price + '', 0) + } + }) + Image(this.goodsItem.imgSrc) + .objectFit(ImageFit.ScaleDown) + .height(130) + .width(100) + .renderMode(ImageRenderMode.Original) + Column() { + Text(this.goodsItem.title) + .fontSize(18) + Text('¥' + this.goodsItem.price) + .fontSize(18) + .fontColor(Color.Red) + } + .margin({left:40}) + } + .height(100) + .width('100%') + .margin({ left: 20 }) + .alignItems(VerticalAlign.Center) + .backgroundColor(Color.White) + } + } + ``` + +4. 新建ShopCartBottom组件,ShopCartBottom组件效果图如下: + + ![](figures/7.png) + + 代码如下: + + ``` + @Component + struct ShopCartBottom { + @Consume totalPrice: number + + build() { + Row() { + Text('Total: ¥' + this.totalPrice) + .fontColor(Color.Red) + .fontSize(18) + .margin({ left: 20 }) + .width(150) + Text('Check Out') + .fontColor(Color.Black) + .fontSize(18) + .margin({ right: 20, left: 180 }) + .onClick(() => { + prompt.showToast({ + message: 'Checking Out', + duration: 10, + bottom: 100 + }) + }) + } + .height(30) + .width('100%') + .backgroundColor('#FF7FFFD4') + .alignItems(VerticalAlign.Bottom) + } + } + ``` + + +# 构建我的页签 + +![](figures/mypage.png) + +从上面效果图可以看出,主界面我的页签主要由下面四部分组成: + +1. 顶部的水平布局。 +2. 顶部下面的文本加数字的水平List。 +3. My Transactio模块,图片加文本的水平List。 +4. More模块,图片加文本的Grid。 + +在本任务中,我们构建主页我的页签,主要可以划分成下面几步: + +1. 在pages目录下面新建一个ETS Page 命名为MyPage.ets,在config.json文件pages属性中也会自动添加“pages/MyPage”页面路由。 +2. 在MyPage.ets文件中添加入口组件(MyInfo),组件内容如下: + + ``` + import {getMenu,getTrans,getMore} from '../model/GoodsDataModels' + import {Menu, ImageItem} from '../model/Menu' + @Entry + @Component + export struct MyInfo { + build() { + Column() { + Row() { + Image($r('app.media.icon_user')) + .objectFit(ImageFit.Contain) + .height(50) + .width(50) + .margin({left:10}) + .renderMode(ImageRenderMode.Original) + Column() { + Text('John Doe') + .fontSize(15) + Text('Member Name : John Doe >') + .fontSize(15) + } + .height(60) + .margin({ left: 20, top: 10 }) + .alignItems(HorizontalAlign.Start) + } + + TopList() + MyTransList() + MoreGrid() + + } + .alignItems(HorizontalAlign.Start) + .width('100%') + .height('100%') + .flexGrow(1) + } + } + ``` + + 入口组件中还包含TopList,MyTransList和MoreGrid三个子组件。 + +3. 在MyPage.ets文件中新建TopList组件,效果图如下: + + ![](figures/11.png) + + 代码如下: + + ``` + @Component + struct TopList { + private menus: Menu1[] = getMenu() + + build() { + Row() { + List() { + ForEach(this.menus, item => { + ListItem() { + MenuItem({ menu: item }) + } + }, item => item.id.toString()) + } + .height('100%') + .width('100%') + .margin({ top: 5,left: 10}) + .edgeEffect(EdgeEffect.None) + .listDirection(Axis.Horizontal) + } + .width('100%') + .height(50) + } + } + ``` + + getMenu\(\)方法在上文中已有定义,是获取菜单列表的方法,TopList的子组件MenuItem内容如下: + + ``` + @Component + struct MenuItem { + private menu: Menu1 + + build() { + Column() { + Text(this.menu.title) + .fontSize(15) + Text(this.menu.num + '') + .fontSize(13) + + } + .height(50) + .width(100) + .margin({ left: 8, right: 8 }) + .alignItems(HorizontalAlign.Start) + .backgroundColor(Color.White) + } + } + ``` + +4. 在MyPage.ets文件中新建MyTransList组件和MoreGrid组件,MyTransList组件效果如如下: + + ![](figures/12.png) + + 代码如下: + + ``` + @Component + struct MyTransList { + private imageItems: ImageItem[] = getTrans() + + build() { + Column() { + Text('My Transaction') + .fontSize(20) + .margin({ left: 10 }) + .width('100%') + .height(30) + Row() { + List() { + ForEach(this.imageItems, item => { + ListItem() { + DataItem({ imageItem: item }) + } + }, item => item.id.toString()) + } + .height(70) + .width('100%') + .edgeEffect(EdgeEffect.None) + .margin({ top: 5 }) + .padding({ left: 16, right: 16 }) + .listDirection(Axis.Horizontal) + } + } + .height(120) + } + } + ``` + + MoreGrid组件效果图如下: + + ![](figures/13.png) + + 代码如下: + + ``` + @Component + struct MoreGrid { + private gridRowTemplate: string = '' + private imageItems: ImageItem[] = getMore() + private heightValue: number + + aboutToAppear() { + var rows = Math.round(this.imageItems.length / 3); + this.gridRowTemplate = '1fr '.repeat(rows); + this.heightValue = rows * 75; + } + + build() { + Column() { + Text('More') + .fontSize(20) + .margin({ left: 10 }) + .width('100%') + .height(30) + Scroll() { + Grid() { + ForEach(this.imageItems, (item: ImageItem) => { + GridItem() { + DataItem({ imageItem: item }) + } + }, (item: ImageItem) => item.id.toString()) + } + .rowsTemplate(this.gridRowTemplate) + .columnsTemplate('1fr 1fr 1fr') + .columnsGap(8) + .rowsGap(8) + .height(this.heightValue) + } + .padding({ left: 16, right: 16 }) + } + .height(400) + } + } + ``` + + 在MyTransList和MoreGrid组件中都包含子组件DataItem,为避免的重复代码,可以把多次要用到的结构体组件化,这里的结构体就是图片加上文本的上下结构体,DataItem组件内容如下: + + ``` + @Component + struct DataItem { + private imageItem: ImageItem + + build() { + Column() { + Image(this.imageItem.imageSrc) + .objectFit(ImageFit.Contain) + .height(50) + .width(50) + .renderMode(ImageRenderMode.Original) + Text(this.imageItem.title) + .fontSize(15) + + } + .height(70) + .width(150) + .margin({ left: 10, right: 10 }) + .backgroundColor(Color.White) + } + } + ``` + + +# 构建商品详情页面 + +![](figures/shoppingDetail1.png) + +从上面效果图可以看出,商品详情页面主要由下面五部分组成: + +1. 顶部的返回栏。 +2. Swiper组件。 +3. 中间多个Text组件组成的布局。 +4. 参数列表。 +5. 底部的Buy。 + +在本任务中,把上面每一部分都封装成一个组件,然后再放到入口组件内,当点击顶部返回图标时返回到主页面的商品列表页签,点击底部Buy时,会触发进度条弹窗 + +1. 在pages目录下面新建一个ETS Page, 命名为ShoppingDetail.ets,config.json文件pages属性中也会自动添加“pages/ShoppingDetail”页面路由。 +2. 在ShoppingDetail.ets文件中创建入口组件,组件内容如下: + + ``` + @Entry + @Component + struct ShoppingDetail { + private arsItems: ArsData[] = getArs() + + build() { + Column() { + DetailTop() + Scroll() { + Column() { + SwiperTop() + DetailText() + DetailArsList({ arsItems: this.arsItems }) + Image($r('app.media.computer1')) + .height(220) + .width('100%') + .margin({ top: 30 }) + Image($r('app.media.computer2')) + .height(220) + .width('100%') + .margin({ top: 30 }) + Image($r('app.media.computer3')) + .height(220) + .width('100%') + .margin({ top: 30 }) + Image($r('app.media.computer4')) + .height(220) + .width('100%') + .margin({ top: 30 }) + Image($r('app.media.computer5')) + .height(220) + .width('100%') + .margin({ top: 30 }) + Image($r('app.media.computer6')) + .height(220) + .width('100%') + .margin({ top: 30 }) + } + .width('100%') + .flexGrow(1) + } + .scrollable(ScrollDirection.Vertical) + + DetailBottom() + } + .height('90%') + .width('100%') + } + } + ``` + + 其中顶部DetailTop组件效果图如下: + + ![](figures/d1.png) + + 代码如下: + + ``` + @Component + struct DetailTop { + build() { + Column() { + Row() { + Image($r('app.media.icon_return')) + .height(40) + .width(40) + .margin({left: 20}) + .onClick(() => { + router.push({ + uri: "pages/HomePage" + }) + }) + + } + .width('100%') + .height(35) + .backgroundColor('#FF87CEEB') + } + .width('100%') + .height(40) + } + } + ``` + +3. SwiperTop组件效果图如下: + + ![](figures/d2.png) + + 代码如下: + + ``` + @Component + struct SwiperTop { + build() { + Column() { + Swiper() { + Image($r('app.media.computer1')) + .height(220) + .width('100%') + Image($r('app.media.computer2')) + .height(220) + .width('100%') + Image($r('app.media.computer3')) + .height(220) + .width('100%') + Image($r('app.media.computer4')) + .height(220) + .width('100%') + Image($r('app.media.computer5')) + .height(220) + .width('100%') + Image($r('app.media.computer6')) + .height(220) + .width('100%') + } + .index(0) + .autoPlay(true) + .interval(3000) + .indicator(true) + .loop(true) + .height(250) + .width('100%') + } + .height(250) + .width('100%') + } + } + ``` + +4. DetailText组件效果图如下: + + ![](figures/d3.png) + + 代码如下: + + ``` + @Component + struct DetailText { + build() { + Column() { + Row() { + Image($r('app.media.icon_promotion')) + .objectFit(ImageFit.Contain) + .height(30) + .width(30) + .margin({ left: 10 }) + Text('Special Offer: ¥9999') + .fontColor(Color.White) + .fontSize(20) + .margin({ left: 10 }) + + } + .width('100%') + .height(35) + .backgroundColor(Color.Red) + + Column() { + Text('New Arrival: HUAWEI MateBook X Pro 2021') + .fontSize(18) + .margin({ left: 10 }) + .alignSelf(ItemAlign.Start) + Text('13.9-Inch, 11th Gen Intel® Core™ i7, 16 GB of Memory, 512 GB of Storage, Ultra-slim Business Laptop, 3K FullView Display, Multi-screen + Collaboration, Emerald Green') + .fontSize(14) + .margin({ left: 10 }) + Row() { + Image($r('app.media.icon_buy')) + .objectFit(ImageFit.Contain) + .height(30) + .width(30) + .margin({ left: 10 }) + Text('Limited offer') + .fontSize(15) + .fontColor(Color.Red) + .margin({ left: 100 }) + + } + .backgroundColor(Color.Pink) + .width('100%') + .height(45) + .margin({ top: 10 }) + + Text(' Shipment: 2-day shipping') + .fontSize(13) + .fontColor(Color.Red) + .margin({ left: 10, top: 5 }) + .alignSelf(ItemAlign.Start) + Text(' Ship To: Hubei,Wuhan,China') + .fontSize(13) + .fontColor(Color.Red) + .margin({ left: 10, top: 5 }) + .alignSelf(ItemAlign.Start) + .onClick(() => { + prompt.showDialog({ title: 'select address', }) + + }) + Text('Guarantee: Genuine guaranteed') + .fontSize(13) + .margin({ left: 10, top: 5 }) + .alignSelf(ItemAlign.Start) + } + .height(170) + .width('100%') + } + .height(180) + .width('100%') + } + } + ``` + + DetailArsList组件效果图如下: + + ![](figures/d4.png) + + 代码如下: + + ``` + @Component + struct DetailArsList{ + private arsItems: ArsData[] + build() { + Scroll() { + Column() { + List() { + ForEach(this.arsItems, item => { + ListItem() { + ArsListItem({ arsItem: item }) + } + }, item => item.id.toString()) + } + .height('100%') + .width('100%') + .margin({ top: 5 }) + .listDirection(Axis.Vertical) + } + .height(200) + } + } + } + ``` + + ArsListItem组件代码如下: + + ``` + @Component + struct ArsListItem { + private arsItem: ArsData + + build() { + Row() { + Text(this.arsItem.title + " :") + .fontSize(11) + .margin({ left: 20 }) + .flexGrow(1) + Text(this.arsItem.content) + .fontSize(11) + .margin({ right: 20 }) + + } + .height(14) + .width('100%') + .backgroundColor(Color.White) + } + } + ``` + +5. DetailBottom组件效果图如下: + + ![](figures/d5.png) + + 代码如下: + + ``` + @Component + struct DetailBottom { + @Provide + private value: number= 1 + dialogController: CustomDialogController = new CustomDialogController({ + builder: DialogExample({ action: this.onAccept }), + cancel: this.existApp, + autoCancel: true + }); + + onAccept() { + + } + + existApp() { + + } + + build() { + Column() { + Text('Buy') + .width(40) + .height(25) + .fontSize(20) + .fontColor(Color.White) + .onClick(() => { + this.value = 1 + this.dialogController.open() + }) + } + .alignItems(HorizontalAlign.Center) + .backgroundColor(Color.Red) + .width('100%') + .height('10%') + } + } + ``` + + DialogExample自定义弹窗组件效果图如下: + + ![](figures/shoppingDetail2.png) + + 代码如下: + + ``` + @CustomDialog + struct DialogExample { + @Consume + private value: number + controller: CustomDialogController; + action: () => void; + + build() { + Column() { + Progress({ value: this.value++ >= 100 ? 100 : this.value, total: 100, style: ProgressStyle.Capsule }) + .height(50) + .width(100) + .margin({ top: 5 }) + + } + .height(60) + .width(100) + } + } + ``` + + +# 完整代码 + +链接如下: + +[gitee源码](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/ShoppingEts) + +# 相关概念与参考 + +## API 参考 + +1. [Tabs组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-container-tabs.md) +2. [CustomDialog自定义弹窗](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-methods-custom-dialog-box.md) +3. [List组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-container-list.md) +4. [Grid组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-container-grid.md) +5. [Image组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-image.md) +6. [Button组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-button.md) +7. [Text组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-text.md) +8. [Progress组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-progress.md) +9. [Navigator组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-container-navigator.md) +10. [TabContent组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-container-tabcontent.md) +11. [Row组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-container-row.md) +12. [Colunm组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-container-column.md) +13. [Flex组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-container-flex.md) +14. [Scroll组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-container-scroll.md) + +# 总结 + +本篇CodeLab灵活使用了一些组件来实现页面效果: + +1. 使用Tabs组件完成商品分类。 +2. 使用List组件完成商品列表、图片列表、参数列表等。 +3. 使用Swiper组件完成图片的循环轮播。 +4. 使用Toggle组件完成购物车商品的选择。 + + diff --git a/ETSUI/ShoppingEts/RELEASE-NOTES.md b/ETSUI/ShoppingEts/RELEASE-NOTES.md new file mode 100644 index 0000000000000000000000000000000000000000..ea23a13e3d4407d06cba3aa7155a23e5081b50b4 --- /dev/null +++ b/ETSUI/ShoppingEts/RELEASE-NOTES.md @@ -0,0 +1,2 @@ +1.0.0 +1.Initial version \ No newline at end of file diff --git a/ETSUI/ShoppingEts/build.gradle b/ETSUI/ShoppingEts/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..61b473ade5001661566d1814a517fad8fac436bf --- /dev/null +++ b/ETSUI/ShoppingEts/build.gradle @@ -0,0 +1,35 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + supportSystem "standard" +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } + dependencies { + classpath 'com.huawei.ohos:hap:3.0.3.4' + classpath 'com.huawei.ohos:decctest:1.2.6.0' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } +} + diff --git a/ETSUI/ShoppingEts/entry/.gitignore b/ETSUI/ShoppingEts/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7d5b7a94f4dcf381f03ff21f28f8a2494b58023f --- /dev/null +++ b/ETSUI/ShoppingEts/entry/.gitignore @@ -0,0 +1,2 @@ +/build +/node_modules diff --git a/ETSUI/ShoppingEts/entry/build.gradle b/ETSUI/ShoppingEts/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..a4d33f15106d843d0649c349d723579f0c592204 --- /dev/null +++ b/ETSUI/ShoppingEts/entry/build.gradle @@ -0,0 +1,22 @@ +apply plugin: 'com.huawei.ohos.hap' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + + compileSdkVersion 7 + defaultConfig { + compatibleSdkVersion 7 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13.1' +} diff --git a/ETSUI/ShoppingEts/entry/proguard-rules.pro b/ETSUI/ShoppingEts/entry/proguard-rules.pro new file mode 100644 index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a --- /dev/null +++ b/ETSUI/ShoppingEts/entry/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/ETSUI/ShoppingEts/entry/src/main/config.json b/ETSUI/ShoppingEts/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..4614bc40c889ac61b6f64c7e429e13f749572272 --- /dev/null +++ b/ETSUI/ShoppingEts/entry/src/main/config.json @@ -0,0 +1,69 @@ +{ + "app": { + "bundleName": "com.huawei.cookbook", + "vendor": "example", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "com.example.myapplication", + "name": ".MyApplication", + "mainAbility": ".MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "visible": true, + "srcPath": "MainAbility", + "name": ".MainAbility", + "srcLanguage": "ets", + "icon": "$media:icon", + "description": "$string:description_mainability", + "formsEnabled": false, + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "mode": { + "syntax": "ets", + "type": "pageAbility" + }, + "pages": [ + "pages/HomePage", + "pages/ShoppingCartPage", + "pages/ShoppingDetail", + "pages/MyPage" + ], + "name": ".MainAbility", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} \ No newline at end of file diff --git a/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/app.ets b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..b7a0995c8e441cac86e21e06e7c9071664482b1c --- /dev/null +++ b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/app.ets @@ -0,0 +1,8 @@ +export default { + onCreate() { + console.info('Application onCreate') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} \ No newline at end of file diff --git a/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/ArsData.ets b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/ArsData.ets new file mode 100644 index 0000000000000000000000000000000000000000..96b1b9243a4d8107c2b66562e0fe7ecfcd2bcb9b --- /dev/null +++ b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/ArsData.ets @@ -0,0 +1,12 @@ +let NextId = 0; +export class ArsData { + id: string; + title: string; + content: string; + + constructor(title: string, content: string) { + this.id = `${NextId++}`; + this.title = title; + this.content = content; + } +} diff --git a/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/GoodsData.ets b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/GoodsData.ets new file mode 100644 index 0000000000000000000000000000000000000000..0ce700b72225f3a80016fd6bbda93eb6397630a8 --- /dev/null +++ b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/GoodsData.ets @@ -0,0 +1,26 @@ +let NextId = 0; +export class GoodsData { + id: string; + title: string; + content: string; + price: number; + imgSrc: Resource; + + constructor(title: string, content: string, price: number, imgSrc: Resource) { + this.id = `${NextId++}`; + this.title = title; + this.content = content; + this.price = price; + this.imgSrc = imgSrc; + } +} + +export class IconImage { + id: string; + imgSrc: Resource; + + constructor(imgSrc: Resource) { + this.id = `${NextId++}`; + this.imgSrc = imgSrc; + } +} \ No newline at end of file diff --git a/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/GoodsDataModels.ets b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/GoodsDataModels.ets new file mode 100644 index 0000000000000000000000000000000000000000..7ac016b03996cca3f0b5377bcb275983a707acd5 --- /dev/null +++ b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/GoodsDataModels.ets @@ -0,0 +1,300 @@ +import {GoodsData,IconImage} from './GoodsData' +import {Menu1, ImageItem} from './Menu' +import {ArsData} from './ArsData' + +export function initializeOnStartup(): Array { + let GoodsDataArray: Array = [] + GoodsComposition.forEach(item => { + console.log(item.title); + GoodsDataArray.push(new GoodsData(item.title, item.content, item.price, item.imgSrc)); + }) + return GoodsDataArray; +} + +export function getIconPath(): Array { + let IconPath: Array = [] + iconList.forEach(item => { + IconPath.push(new IconImage(item.imgSrc)); + }) + return IconPath; +} + +export function getIconPathSelect(): Array { + let IconPathSelect: Array = [] + iconListSelect.forEach(item => { + + IconPathSelect.push(new IconImage( item.imgSrc)); + }) + return IconPathSelect; +} + +export function getDetailImages(): Array { + let detailImages: Array = [] + detailImageList.forEach(item => { + + detailImages.push(new IconImage( item.imgSrc)); + }) + return detailImages; +} + + +export function getMenu(): Array { + let MenuArray: Array = [] + MyMenu.forEach(item => { + MenuArray.push(new Menu1(item.title, item.num)); + }) + return MenuArray; +} + +export function getTrans(): Array { + let ImageItemArray: Array = [] + MyTrans.forEach(item => { + ImageItemArray.push(new ImageItem(item.title, item.imageSrc)); + }) + return ImageItemArray; +} + +export function getMore(): Array { + let ImageItemArray: Array = [] + MyMore.forEach(item => { + ImageItemArray.push(new ImageItem(item.title, item.imageSrc)); + }) + return ImageItemArray; +} + +export function getArs(): Array { + let ArsItemArray: Array = [] + ArsList.forEach(item => { + ArsItemArray.push(new ArsData(item.title, item.content)); + }) + return ArsItemArray; +} + +const GoodsComposition: any[] = [ + { + "title": 'HUAWEI nova 8 Pro ', + "content": 'Goes on sale: 10:08', + "price": '3999', + "imgSrc": $r("app.media.HW1") + }, + { + "title": 'HUAWEI Mate 30E Pro 5G', + "content": '3 interest-free payments ', + "price": '5299', + "imgSrc": $r("app.media.HW2") + }, + { + "title": 'HUAWEI MatePad Pro', + "content": 'Flagship ', + "price": '3799', + "imgSrc": $r("app.media.HW3") + }, + { + "title": 'HUAWEI Nova 8 Pro', + "content": 'New arrival ', + "price": '3999', + "imgSrc": $r("app.media.HW4") + }, + { + "title": 'HUAWEI WATCH FIT', + "content": 'Versatile', + "price": '769', + "imgSrc": $r("app.media.HW5") + }, + { + "title": 'HUAWEI nova 8 Pro ', + "content": 'Goes on sale: 10:08', + "price": '3999', + "imgSrc": $r("app.media.HW6") + }, + { + "title": 'HUAWEI Mate 30E Pro 5G', + "content": '3 interest-free payments ', + "price": '5299', + "imgSrc": $r("app.media.HW7") + }, + { + "title": 'HUAWEI MatePad Pro', + "content": 'Flagship ', + "price": '3799', + "imgSrc": $r("app.media.HW8") + }, + { + "title": 'HUAWEI Nova 8 Pro', + "content": 'New arrival ', + "price": '3999', + "imgSrc": $r("app.media.HW9") + }, + { + "title": 'HUAWEI WATCH FIT', + "content": 'Versatile', + "price": '769', + "imgSrc": $r("app.media.HW10") + }, +] + +const iconList: any[] = [ + { + "imgSrc": $r('app.media.icon_buy1') + }, + { + "imgSrc": $r('app.media.icon_shopping_cart') + }, + { + "imgSrc": $r('app.media.icon_my') + }, +] + +const iconListSelect: any[] = [ + { + "imgSrc": $r('app.media.icon_home') + }, + { + "imgSrc": $r('app.media.icon_shopping_cart_select') + }, + { + "imgSrc": $r('app.media.icon_my_select') + }, +] + +const detailImageList: any[] = [ + { + "imgSrc": $r('app.media.computer1') + }, + { + "imgSrc": $r('app.media.computer2') + }, + { + "imgSrc": $r('app.media.computer3') + }, + { + "imgSrc": $r('app.media.computer4') + }, + { + "imgSrc": $r('app.media.computer5') + }, + { + "imgSrc": $r('app.media.computer6') + }, + { + "imgSrc": $r('app.media.computer3') + }, +] + + +const MyMenu: any[] = [ + { + 'title': 'Favorites', + 'num': '10' + }, + { + 'title': 'Searched', + 'num': '1000' + }, + { + 'title': 'Following', + 'num': '100' + }, + { + 'title': 'Followers', + 'num': '10000' + } +] + +const MyTrans: any[] = [ + { + 'title': 'Post: 520', + 'imageSrc': $r("app.media.icon_menu_release") + }, + { + 'title': 'Sold: 520', + 'imageSrc':$r("app.media.icon_menu_sell") + }, + { + 'title': 'Bought: 10', + 'imageSrc': $r("app.media.icon_menu_buy") + } +] + +const MyMore: any[] = [ + { + 'title': 'Guide', + 'imageSrc': $r("app.media.icon_menu_buy") + }, + { + 'title': 'Create', + 'imageSrc': $r("app.media.icon_menu_buy") + }, + { + 'title': 'Poster', + 'imageSrc': $r("app.media.icon_menu_buy") + }, + { + 'title': 'Games', + 'imageSrc': $r("app.media.icon_menu_buy") + }, + { + 'title': 'Jobber', + 'imageSrc': $r("app.media.icon_menu_buy") + }, + { + 'title': 'Myself', + 'imageSrc': $r("app.media.icon_menu_buy") + }, + { + 'title': 'About', + 'imageSrc': $r("app.media.icon_menu_buy") + }, + { + 'title': 'Rental', + 'imageSrc': $r("app.media.icon_menu_buy") + }, + { + 'title': 'Author', + 'imageSrc': $r("app.media.icon_menu_buy") + }, + +] + +const ArsList: any[] = [ + { + 'title': 'Display Size', + 'content': '13.9 inches', + }, + { + 'title': 'Memory', + 'content': '16 GB', + }, + { + 'title': 'Marketing Name', + 'content': 'HUAWEI MateBook X Pro', + }, + { + 'title': 'Color Gamut', + 'content': '100% sRGB color gamut (Typical)', + }, + { + 'title': 'Battery', + 'content': '56 Wh (rated capacity)', + }, + { + 'title': 'Storage', + 'content': '512 GB', + }, + { + 'title': 'Resolution', + 'content': '3000x2000', + }, + { + 'title': 'Processor', + 'content': '11th Gen Intel® Core™ i7-1165G7 Processor', + }, + { + 'title': 'CPU Cores', + 'content': '4', + }, + { + 'title': 'Launch Time', + 'content': 'January 2021', + } +] \ No newline at end of file diff --git a/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/Menu.ets b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/Menu.ets new file mode 100644 index 0000000000000000000000000000000000000000..1eebdd5f5e72f6e9498357a88d64b36967790be7 --- /dev/null +++ b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/model/Menu.ets @@ -0,0 +1,25 @@ + +let NextId = 0; +export class Menu1 { + id: string; + title: string; + num: number; + + constructor(title: string, num: number) { + this.id = `${NextId++}`; + this.title = title; + this.num = num; + } +} + +export class ImageItem { + id: string; + title: string; + imageSrc: Resource; + + constructor(title: string, imageSrc: Resource) { + this.id = `${NextId++}`; + this.title = title; + this.imageSrc = imageSrc; + } +} \ No newline at end of file diff --git a/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/HomePage.ets b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/HomePage.ets new file mode 100644 index 0000000000000000000000000000000000000000..b61ba1259dcbedafce0e93a5912a8817986c3381 --- /dev/null +++ b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/HomePage.ets @@ -0,0 +1,193 @@ +import {GoodsData,IconImage} from '../model/GoodsData' +import {initializeOnStartup, getIconPath, getIconPathSelect} from '../model/GoodsDataModels' +import {ShoppingCart} from './ShoppingCartPage.ets' +import {MyInfo} from './MyPage.ets' +import router from '@system.router'; + +@Entry +@Component +struct Index { + @Provide currentPage: number = 1 + private goodsItems: GoodsData[] = initializeOnStartup() + build() { + Column() { + Scroll(){ + Column() { + if (this.currentPage == 1) { + GoodsHome({ goodsItems: this.goodsItems }) + } else if (this.currentPage == 2) { + //购物车列表 + ShoppingCart() + } else { + //我的 + MyInfo() + } + } + .width('100%') + .flexGrow(1) + } + .scrollable(ScrollDirection.Vertical) + HomeBottom() + } + .height('93%') + .width('100%') + .backgroundColor("white") + + } +} + + +@Component +struct HomeBottom { + @Consume currentPage: number + private iconPathTmp: IconImage[] = getIconPath() + private iconPathSelectsTmp: IconImage[] = getIconPathSelect() + @State iconPath: IconImage[] = getIconPath() + + build() { + Row() { + Image(this.iconPath[0].imgSrc) + .objectFit(ImageFit.Contain) + .height(120) + .width(120) + .margin({left:80,top: 20}) + .renderMode(ImageRenderMode.Original) + .onClick(()=>{ + this.iconPath[0] = this.iconPathTmp[0] + this.iconPath[1] = this.iconPathTmp[1] + this.iconPath[2] = this.iconPathTmp[2] + this.currentPage = 1 + }) + Image(this.iconPath[1].imgSrc) + .objectFit(ImageFit.Contain) + .height(120) + .width(120) + .margin({left:80,top: 20}) + .renderMode(ImageRenderMode.Original) + .onClick(()=>{ + this.iconPath[0] = this.iconPathSelectsTmp[0] + this.iconPath[1] = this.iconPathSelectsTmp[1] + this.iconPath[2] = this.iconPathTmp[2] + this.currentPage = 2 + }) + Image(this.iconPath[2].imgSrc) + .objectFit(ImageFit.Contain) + .height(120) + .width(120) + .margin({left:80,top: 20}) + .renderMode(ImageRenderMode.Original) + .onClick(()=>{ + this.iconPath[0] = this.iconPathSelectsTmp[0] + this.iconPath[1] = this.iconPathTmp[1] + this.iconPath[2] = this.iconPathSelectsTmp[2] + this.currentPage = 3 + }) + + } + .backgroundColor(Color.White) + .alignItems(VerticalAlign.Bottom) + .width('100%') + .height('10%') + } +} + + +@Component +struct GoodsList { + private goodsItems: GoodsData[] + + build() { + Column() { + List() { + ForEach(this.goodsItems, item => { + ListItem() { + GoodsListItem({ goodsItem: item }) + } + }, item => item.id.toString()) + } + .height('100%') + .width('100%') + .align(Alignment.Top) + .margin({ top: 10 }) + } + } +} + +@Component +struct GoodsHome { + private goodsItems: GoodsData[] + + build() { + Column() { + Tabs() { + TabContent() { + GoodsList({ goodsItems: this.goodsItems }); + } + .tabBar("Top Sellers") + .backgroundColor(Color.White) + + TabContent() { + GoodsList({ goodsItems: this.goodsItems }); + } + .tabBar("Recommended") + .backgroundColor(Color.White) + + TabContent() { + GoodsList({ goodsItems: this.goodsItems }); + } + .tabBar("Lifestyle") + .backgroundColor(Color.White) + + TabContent() { + GoodsList({ goodsItems: this.goodsItems }); + } + .tabBar("Deals") + .backgroundColor(Color.White) + } + .barWidth(540) + .barHeight(50) + .scrollable(true) + .barMode(BarMode.Scrollable) + .backgroundColor('#007DFF') + .height('100%') + } + .alignItems(HorizontalAlign.Start) + } +} + +@Component +struct GoodsListItem { + private goodsItem: GoodsData + + build() { + Navigator({ target: 'pages/ShoppingDetail' }) { + Row() { + Column() { + Text(this.goodsItem.title) + .fontSize(18) + Text(this.goodsItem.content) + .fontSize(14) + Text('¥' + this.goodsItem.price) + .fontSize(18) + .fontColor(Color.Red) + } + .height(130) + .width('60%') + .margin({ left: 20 }) + .alignItems(HorizontalAlign.Start) + + Image(this.goodsItem.imgSrc) + .objectFit(ImageFit.ScaleDown) + .height(130) + .width('30%') + .renderMode(ImageRenderMode.Original) + .margin({ right: 10, left: 10 }) + + } + .backgroundColor(Color.White) + + } + .params({ goodsData: this.goodsItem }) + .margin({ right: 5 }) + } +} \ No newline at end of file diff --git a/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/MyPage.ets b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/MyPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..8c8085f105e998a7369decb6f953016ccc14a730 --- /dev/null +++ b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/MyPage.ets @@ -0,0 +1,177 @@ +import {getMenu, getTrans, getMore} from '../model/GoodsDataModels' +import {Menu1, ImageItem} from '../model/Menu' + +@Entry +@Component +export +struct MyInfo { + build() { + Column() { + Row() { + Image($r('app.media.icon_user')) + .objectFit(ImageFit.Contain) + .height(50) + .width(50) + .margin({left:10}) + .renderMode(ImageRenderMode.Original) + Column() { + Text('John Doe') + .fontSize(15) + Text('Member Name : John Doe >') + .fontSize(15) + } + .height(60) + .margin({ left: 20, top: 10 }) + .alignItems(HorizontalAlign.Start) + } + + TopList() + MyTransList() + MoreGrid() + + } + .alignItems(HorizontalAlign.Start) + .width('100%') + .height('100%') + .flexGrow(1) + } +} + + +@Component +struct TopList { + private menus: Menu1[] = getMenu() + + build() { + Row() { + List() { + ForEach(this.menus, item => { + ListItem() { + MenuItem({ menu: item }) + } + }, item => item.id.toString()) + } + .height('100%') + .width('100%') + .margin({ top: 5,left: 10}) + .edgeEffect(EdgeEffect.None) + .listDirection(Axis.Horizontal) + } + .width('100%') + .height(50) + } +} + +@Component +struct MyTransList { + private imageItems: ImageItem[] = getTrans() + + build() { + Column() { + Text('My Transaction') + .fontSize(20) + .margin({ left: 10 }) + .width('100%') + .height(30) + Row() { + List() { + ForEach(this.imageItems, item => { + ListItem() { + DataItem({ imageItem: item }) + } + }, item => item.id.toString()) + } + .height(70) + .width('100%') + .edgeEffect(EdgeEffect.None) + .margin({ top: 5 }) + .padding({ left: 16, right: 16 }) + .listDirection(Axis.Horizontal) + } + } + .height(120) + } +} + +@Component +struct MoreGrid { + private gridRowTemplate: string = '' + private imageItems: ImageItem[] = getMore() + private heightValue: number + + aboutToAppear() { + var rows = Math.round(this.imageItems.length / 3); + this.gridRowTemplate = '1fr '.repeat(rows); + this.heightValue = rows * 75; + } + + build() { + Column() { + Text('More') + .fontSize(20) + .margin({ left: 10 }) + .width('100%') + .height(30) + Scroll() { + Grid() { + ForEach(this.imageItems, (item: ImageItem) => { + GridItem() { + DataItem({ imageItem: item }) + } + }, (item: ImageItem) => item.id.toString()) + } + .rowsTemplate(this.gridRowTemplate) + .columnsTemplate('1fr 1fr 1fr') + .columnsGap(8) + .rowsGap(8) + .height(this.heightValue) + } + .padding({ left: 16, right: 16 }) + } + .height(400) + } +} + + +@Component +struct DataItem { + private imageItem: ImageItem + + build() { + Column() { + Image(this.imageItem.imageSrc) + .objectFit(ImageFit.Contain) + .height(50) + .width(50) + .renderMode(ImageRenderMode.Original) + Text(this.imageItem.title) + .fontSize(15) + + } + .height(70) + .width(150) + .margin({ left: 10, right: 10 }) + .backgroundColor(Color.White) + } +} + +@Component +struct MenuItem { + private menu: Menu1 + + build() { + Column() { + Text(this.menu.title) + .fontSize(15) + Text(this.menu.num + '') + .fontSize(13) + + } + .height(50) + .width(100) + .margin({ left: 8, right: 8 }) + .alignItems(HorizontalAlign.Start) + .backgroundColor(Color.White) + } +} + diff --git a/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/ShoppingCartPage.ets b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/ShoppingCartPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..c1bd97627750554e6700e9b4ee3366e85c8d6890 --- /dev/null +++ b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/ShoppingCartPage.ets @@ -0,0 +1,122 @@ +import {GoodsData} from '../model/GoodsData' +import {initializeOnStartup} from '../model/GoodsDataModels' +import prompt from '@system.prompt'; + +@Entry +@Component + export struct ShoppingCart { + @Provide totalPrice: number = 0 + private goodsItems: GoodsData[] = initializeOnStartup() + + build() { + Column() { + Column() { + Text('ShoppingCart') + .fontColor(Color.Black) + .fontSize(25) + .margin({ left: 60, right: 60 }) + .align(Alignment.Center) + } + .backgroundColor('#FF00BFFF') + .width('100%') + .height(30) + + ShopCartList({ goodsItems: this.goodsItems }); + ShopCartBottom() + } + .height('100%') + .width('100%') + .alignItems(HorizontalAlign.Start) + } +} + +@Component +struct ShopCartList { + private goodsItems: GoodsData[] + + build() { + Column() { + List() { + ForEach(this.goodsItems, item => { + ListItem() { + ShopCartListItem({ goodsItem: item }) + } + }, item => item.id.toString()) + } + .height('100%') + .width('100%') + .align(Alignment.Top) + .margin({ top: 5 }) + } + .height('90%') + } +} + +@Component +struct ShopCartListItem { + @Consume totalPrice: number + private goodsItem: GoodsData + + build() { + Row() { + Toggle({ type: ToggleType.Checkbox }) + .width(13) + .height(13) + .onChange((isOn: boolean) => { + if (isOn) { + this.totalPrice += parseInt(this.goodsItem.price + '', 0) + } else { + this.totalPrice -= parseInt(this.goodsItem.price + '', 0) + } + }) + Image(this.goodsItem.imgSrc) + .objectFit(ImageFit.ScaleDown) + .height(130) + .width(100) + .renderMode(ImageRenderMode.Original) + Column() { + Text(this.goodsItem.title) + .fontSize(18) + Text('¥' + this.goodsItem.price) + .fontSize(18) + .fontColor(Color.Red) + } + .margin({left:40}) + } + .height(100) + .width('100%') + .margin({ left: 20 }) + .alignItems(VerticalAlign.Center) + .backgroundColor(Color.White) + } +} + +@Component +struct ShopCartBottom { + @Consume totalPrice: number + + build() { + Row() { + Text('Total: ¥' + this.totalPrice) + .fontColor(Color.Red) + .fontSize(18) + .margin({ left: 20 }) + .width(150) + Text('Check Out') + .fontColor(Color.Black) + .fontSize(18) + .margin({ right: 20, left: 180 }) + .onClick(() => { + prompt.showToast({ + message: 'Checking Out', + duration: 10, + bottom: 100 + }) + }) + } + .height(30) + .width('100%') + .backgroundColor('#FF7FFFD4') + .alignItems(VerticalAlign.Bottom) + } +} diff --git a/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/ShoppingDetail.ets b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/ShoppingDetail.ets new file mode 100644 index 0000000000000000000000000000000000000000..61f82c12445d7ba34874f4b89cf1ce26c7d0fe1f --- /dev/null +++ b/ETSUI/ShoppingEts/entry/src/main/ets/MainAbility/pages/ShoppingDetail.ets @@ -0,0 +1,296 @@ +import router from '@system.router'; +import {ArsData} from '../model/ArsData' +import {getArs, getDetailImages} from '../model/GoodsDataModels' +import prompt from '@system.prompt'; + +@Entry +@Component +struct ShoppingDetail { + private arsItems: ArsData[] = getArs() + + build() { + Column() { + DetailTop() + Scroll() { + Column() { + SwiperTop() + DetailText() + DetailArsList({ arsItems: this.arsItems }) + Image($r('app.media.computer1')) + .height(220) + .width('100%') + .margin({ top: 30 }) + Image($r('app.media.computer2')) + .height(220) + .width('100%') + .margin({ top: 30 }) + Image($r('app.media.computer3')) + .height(220) + .width('100%') + .margin({ top: 30 }) + Image($r('app.media.computer4')) + .height(220) + .width('100%') + .margin({ top: 30 }) + Image($r('app.media.computer5')) + .height(220) + .width('100%') + .margin({ top: 30 }) + Image($r('app.media.computer6')) + .height(220) + .width('100%') + .margin({ top: 30 }) + } + .width('100%') + .flexGrow(1) + } + .scrollable(ScrollDirection.Vertical) + + DetailBottom() + } + .height('90%') + .width('100%') + + + } +} + +@Component +struct DetailTop { + build() { + Column() { + Row() { + Image($r('app.media.icon_return')) + .height(40) + .width(40) + .margin({left: 20}) + .onClick(() => { + router.push({ + uri: "pages/HomePage" + }) + }) + + } + .width('100%') + .height(35) + .backgroundColor('#FF87CEEB') + } + .width('100%') + .height(40) + } +} + +@Component +struct SwiperTop { + build() { + Column() { + Swiper() { + Image($r('app.media.computer1')) + .height(220) + .width('100%') + Image($r('app.media.computer2')) + .height(220) + .width('100%') + Image($r('app.media.computer3')) + .height(220) + .width('100%') + Image($r('app.media.computer4')) + .height(220) + .width('100%') + Image($r('app.media.computer5')) + .height(220) + .width('100%') + Image($r('app.media.computer6')) + .height(220) + .width('100%') + } + .index(0) + .autoPlay(true) + .interval(3000) + .indicator(true) + .loop(true) + .height(250) + .width('100%') + } + .height(250) + .width('100%') + } +} + +@Component +struct DetailText { + build() { + Column() { + Row() { + Image($r('app.media.icon_promotion')) + .objectFit(ImageFit.Contain) + .height(30) + .width(30) + .margin({ left: 10 }) + Text('Special Offer: ¥9999') + .fontColor(Color.White) + .fontSize(20) + .margin({ left: 10 }) + + } + .width('100%') + .height(35) + .backgroundColor(Color.Red) + + Column() { + Text('New Arrival: HUAWEI MateBook X Pro 2021') + .fontSize(18) + .margin({ left: 10 }) + .alignSelf(ItemAlign.Start) + Text('13.9-Inch, 11th Gen Intel® Core™ i7, 16 GB of Memory, 512 GB of Storage, Ultra-slim Business Laptop, 3K FullView Display, Multi-screen Collaboration, Emerald Green') + .fontSize(14) + .margin({ left: 10 }) + Row() { + Image($r('app.media.icon_buy')) + .objectFit(ImageFit.Contain) + .height(30) + .width(30) + .margin({ left: 10 }) + Text('Limited offer') + .fontSize(15) + .fontColor(Color.Red) + .margin({ left: 100 }) + + } + .backgroundColor(Color.Pink) + .width('100%') + .height(45) + .margin({ top: 10 }) + + Text(' Shipment: 2-day shipping') + .fontSize(13) + .fontColor(Color.Red) + .margin({ left: 10, top: 5 }) + .alignSelf(ItemAlign.Start) + Text(' Ship To: Hubei,Wuhan,China') + .fontSize(13) + .fontColor(Color.Red) + .margin({ left: 10, top: 5 }) + .alignSelf(ItemAlign.Start) + .onClick(() => { + prompt.showDialog({ title: 'select address', }) + + }) + Text('Guarantee: Genuine guaranteed') + .fontSize(13) + .margin({ left: 10, top: 5 }) + .alignSelf(ItemAlign.Start) + } + .height(170) + .width('100%') + } + .height(180) + .width('100%') + } +} + + +@Component +struct DetailArsList { + private arsItems: ArsData[] + + build() { + Scroll() { + Column() { + List() { + ForEach(this.arsItems, item => { + ListItem() { + ArsListItem({ arsItem: item }) + } + }, item => item.id.toString()) + } + .height('100%') + .width('100%') + .margin({ top: 5 }) + .listDirection(Axis.Vertical) + } + .height(200) + } + } +} + +@Component +struct ArsListItem { + private arsItem: ArsData + + build() { + Row() { + Text(this.arsItem.title + " :") + .fontSize(11) + .margin({ left: 20 }) + .flexGrow(1) + Text(this.arsItem.content) + .fontSize(11) + .margin({ right: 20 }) + + } + .height(14) + .width('100%') + .backgroundColor(Color.White) + } +} + + +@CustomDialog +struct DialogExample { + @Consume + private value: number + controller: CustomDialogController; + action: () => void; + + build() { + Column() { + Progress({ value: this.value++ >= 100 ? 100 : this.value, total: 100, style: ProgressStyle.Capsule }) + .height(50) + .width(100) + .margin({ top: 5 }) + + } + .height(60) + .width(100) + + + } +} + +@Component +struct DetailBottom { + @Provide + private value: number= 1 + dialogController: CustomDialogController = new CustomDialogController({ + builder: DialogExample({ action: this.onAccept }), + cancel: this.existApp, + autoCancel: true + }); + + onAccept() { + + } + + existApp() { + + } + + build() { + Column() { + Text('Buy') + .width(40) + .height(25) + .fontSize(20) + .fontColor(Color.White) + .onClick(() => { + this.value = 1 + this.dialogController.open() + }) + } + .alignItems(HorizontalAlign.Center) + .backgroundColor(Color.Red) + .width('100%') + .height('10%') + } +} \ No newline at end of file diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/element/string.json b/ETSUI/ShoppingEts/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..03b8532c53ca563f8ed6b1e21d20ad3f67a68906 --- /dev/null +++ b/ETSUI/ShoppingEts/entry/src/main/resources/base/element/string.json @@ -0,0 +1,12 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "entry_MainAbility" + }, + { + "name": "description_mainability", + "value": "ETS_Empty Ability" + } + ] +} \ No newline at end of file diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW1.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW1.png new file mode 100644 index 0000000000000000000000000000000000000000..c14053233a161826197f2b1bb5ba26f4af1fe33c Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW1.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW10.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW10.png new file mode 100644 index 0000000000000000000000000000000000000000..e9a41a3dd1b8b4fc51911ae266177d4ba02edfca Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW10.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW2.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW2.png new file mode 100644 index 0000000000000000000000000000000000000000..d3051e228bc7be3df44f1e1adbd1adf9f8d0bc4a Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW2.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW3.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW3.png new file mode 100644 index 0000000000000000000000000000000000000000..3ef9053332df6ea36303113f06cab828632b54a2 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW3.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW4.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW4.png new file mode 100644 index 0000000000000000000000000000000000000000..45bf20d16a268649345bc964b68948d1b262d626 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW4.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW5.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW5.png new file mode 100644 index 0000000000000000000000000000000000000000..849dec3b281c1a72b49e3fc7f180f6bc870fd74d Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW5.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW6.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW6.png new file mode 100644 index 0000000000000000000000000000000000000000..78deb42f96210c86483ec9feb1d8550064a63ee1 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW6.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW7.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW7.png new file mode 100644 index 0000000000000000000000000000000000000000..a47fec66f35167ff0f53a50839a582fb102357c5 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW7.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW8.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW8.png new file mode 100644 index 0000000000000000000000000000000000000000..417a04a54bbf47fe383073c7e90b77630b50bbb7 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW8.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW9.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW9.png new file mode 100644 index 0000000000000000000000000000000000000000..20c5239a9e4c42fcc4ab3d9b4d32f04b7bd4376e Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/HW9.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer1.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer1.png new file mode 100644 index 0000000000000000000000000000000000000000..3f780ef292cc5431d624ab80a491662532863d10 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer1.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer2.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer2.png new file mode 100644 index 0000000000000000000000000000000000000000..b034531da2ea5368e46446142fa0b48b4f02d99e Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer2.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer3.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer3.png new file mode 100644 index 0000000000000000000000000000000000000000..a85a6d3eca9208e21685fe56d58949a3ab90dbb6 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer3.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer4.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer4.png new file mode 100644 index 0000000000000000000000000000000000000000..7a6f195d7495a7a8201d6cf4c70e3eca097b4293 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer4.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer5.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer5.png new file mode 100644 index 0000000000000000000000000000000000000000..056d5ba0d2d283cb9db695c1528f4123abee68e6 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer5.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer6.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer6.png new file mode 100644 index 0000000000000000000000000000000000000000..056d5ba0d2d283cb9db695c1528f4123abee68e6 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer6.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer7.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer7.png new file mode 100644 index 0000000000000000000000000000000000000000..277e8c45a028d94129ecd6cd0eb03f05666b2101 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer7.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer8.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer8.png new file mode 100644 index 0000000000000000000000000000000000000000..75e52ff4c009564f3603ebe833b00498bd6bae02 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/computer8.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_buy.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_buy.png new file mode 100644 index 0000000000000000000000000000000000000000..6e81aff9bf1cc0694da7aa400212dd2501a0ddd3 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_buy.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_buy1.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_buy1.png new file mode 100644 index 0000000000000000000000000000000000000000..8b62376d709e0459a442a91ff86f1f421c0e114e Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_buy1.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_close.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_close.png new file mode 100644 index 0000000000000000000000000000000000000000..69e0228930c3cbcc75e4cfe4b04bbcf1c4f793d1 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_close.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_home.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_home.png new file mode 100644 index 0000000000000000000000000000000000000000..bb23b007555809e7b72af6edc7408514ece959e1 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_home.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_menu_buy.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_menu_buy.png new file mode 100644 index 0000000000000000000000000000000000000000..3110e637f77f48b238c163a86d4d46611e4dac80 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_menu_buy.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_menu_release.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_menu_release.png new file mode 100644 index 0000000000000000000000000000000000000000..b8e36aac6d4255ccef708a0f1e35e5de41114326 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_menu_release.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_menu_sell.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_menu_sell.png new file mode 100644 index 0000000000000000000000000000000000000000..e76c9ae6756fca5c51e6feea66d14386fa85d2d9 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_menu_sell.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_message.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_message.png new file mode 100644 index 0000000000000000000000000000000000000000..4d330b42415639fce3966594ed47eb75662859d2 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_message.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_message_select.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_message_select.png new file mode 100644 index 0000000000000000000000000000000000000000..ccb928d92338f6717860182b0baeba5e670520f4 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_message_select.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_more.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_more.png new file mode 100644 index 0000000000000000000000000000000000000000..a137fb3a56ebd52a7f1ae2bad7ecf3b5a64fad5b Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_more.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_my.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_my.png new file mode 100644 index 0000000000000000000000000000000000000000..327a90d295d89f5222ca97072e3de8036e9a7f52 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_my.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_my_select.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_my_select.png new file mode 100644 index 0000000000000000000000000000000000000000..4106e5e27443c7f023c61458c43eefa0eca40280 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_my_select.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_pin.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_pin.png new file mode 100644 index 0000000000000000000000000000000000000000..d82f70e7b6b28f08e9222f622bec6626fe72274b Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_pin.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_promotion.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_promotion.png new file mode 100644 index 0000000000000000000000000000000000000000..dc81730ac0aace6bfe3aa29bd9cd1de4d873cff2 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_promotion.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_return.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_return.png new file mode 100644 index 0000000000000000000000000000000000000000..7731718a55294ff7b8c5a852204675290cd86814 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_return.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_return1.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_return1.png new file mode 100644 index 0000000000000000000000000000000000000000..21ef5b27d9b5c88991bfbbce66cf71fa783e6525 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_return1.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_share.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_share.png new file mode 100644 index 0000000000000000000000000000000000000000..0d4c416922487483e99aef7081744dc54281e39c Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_share.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_shopping_cart.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_shopping_cart.png new file mode 100644 index 0000000000000000000000000000000000000000..c995e8fc6d25029ee27f0760585bc403861dade5 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_shopping_cart.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_shopping_cart_select.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_shopping_cart_select.png new file mode 100644 index 0000000000000000000000000000000000000000..0e24df117362ed8337ebf8a30d57176dd35783c9 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_shopping_cart_select.png differ diff --git a/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_user.png b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_user.png new file mode 100644 index 0000000000000000000000000000000000000000..873b52f9560c98347ccce32263f8add0250fc410 Binary files /dev/null and b/ETSUI/ShoppingEts/entry/src/main/resources/base/media/icon_user.png differ diff --git a/ETSUI/ShoppingEts/figures/1.png b/ETSUI/ShoppingEts/figures/1.png new file mode 100644 index 0000000000000000000000000000000000000000..fad996d89adef903015da2c1e390625540cb00fb Binary files /dev/null and b/ETSUI/ShoppingEts/figures/1.png differ diff --git a/ETSUI/ShoppingEts/figures/11.png b/ETSUI/ShoppingEts/figures/11.png new file mode 100644 index 0000000000000000000000000000000000000000..efcbc4bd4935d3a86b32bb8f0e79098227888680 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/11.png differ diff --git a/ETSUI/ShoppingEts/figures/12.png b/ETSUI/ShoppingEts/figures/12.png new file mode 100644 index 0000000000000000000000000000000000000000..a3f578a8fc54000b8d1d9a3d2e11128aac3c1343 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/12.png differ diff --git a/ETSUI/ShoppingEts/figures/13.png b/ETSUI/ShoppingEts/figures/13.png new file mode 100644 index 0000000000000000000000000000000000000000..e0fb1cab6bd2958bb981f9186dc1702f8c9d3fe2 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/13.png differ diff --git a/ETSUI/ShoppingEts/figures/1_zh-cn_image_0000001160725256.png b/ETSUI/ShoppingEts/figures/1_zh-cn_image_0000001160725256.png new file mode 100644 index 0000000000000000000000000000000000000000..e907467c33b91c6702bb2af53f41adc75a68efa1 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/1_zh-cn_image_0000001160725256.png differ diff --git a/ETSUI/ShoppingEts/figures/2.png b/ETSUI/ShoppingEts/figures/2.png new file mode 100644 index 0000000000000000000000000000000000000000..8e12807134e430c51871817a137a4c23d1e9464a Binary files /dev/null and b/ETSUI/ShoppingEts/figures/2.png differ diff --git a/ETSUI/ShoppingEts/figures/3.png b/ETSUI/ShoppingEts/figures/3.png new file mode 100644 index 0000000000000000000000000000000000000000..e4843a698436488c5fa26df7278e571a0337a7c3 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/3.png differ diff --git a/ETSUI/ShoppingEts/figures/5.png b/ETSUI/ShoppingEts/figures/5.png new file mode 100644 index 0000000000000000000000000000000000000000..159ede1141a052ce5076e92a5ab2da28e6761ffa Binary files /dev/null and b/ETSUI/ShoppingEts/figures/5.png differ diff --git a/ETSUI/ShoppingEts/figures/6.png b/ETSUI/ShoppingEts/figures/6.png new file mode 100644 index 0000000000000000000000000000000000000000..b8aa8d3f01fff6d72c9d4b2f21f61075b96a6c02 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/6.png differ diff --git a/ETSUI/ShoppingEts/figures/7.png b/ETSUI/ShoppingEts/figures/7.png new file mode 100644 index 0000000000000000000000000000000000000000..bb05a2ff93c7fbd869631044d9339c1b50ca087b Binary files /dev/null and b/ETSUI/ShoppingEts/figures/7.png differ diff --git a/ETSUI/ShoppingEts/figures/8.png b/ETSUI/ShoppingEts/figures/8.png new file mode 100644 index 0000000000000000000000000000000000000000..1ff5f46514ad3af700a0d4c88fce3f6326a1ea13 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/8.png differ diff --git a/ETSUI/ShoppingEts/figures/HoomPage.png b/ETSUI/ShoppingEts/figures/HoomPage.png new file mode 100644 index 0000000000000000000000000000000000000000..5f46091b47fe0602de635f3fc123de57eb7c2427 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/HoomPage.png differ diff --git a/ETSUI/ShoppingEts/figures/d1.png b/ETSUI/ShoppingEts/figures/d1.png new file mode 100644 index 0000000000000000000000000000000000000000..4189cb9bdc0e5dd7107ad70ba7bbfe89c9d9b51a Binary files /dev/null and b/ETSUI/ShoppingEts/figures/d1.png differ diff --git a/ETSUI/ShoppingEts/figures/d2.png b/ETSUI/ShoppingEts/figures/d2.png new file mode 100644 index 0000000000000000000000000000000000000000..945a6e132a4ab2e89548a81ac258f29312e08a0f Binary files /dev/null and b/ETSUI/ShoppingEts/figures/d2.png differ diff --git a/ETSUI/ShoppingEts/figures/d3.png b/ETSUI/ShoppingEts/figures/d3.png new file mode 100644 index 0000000000000000000000000000000000000000..0ddeb029c1064a335d20165befc7f020a64f374e Binary files /dev/null and b/ETSUI/ShoppingEts/figures/d3.png differ diff --git a/ETSUI/ShoppingEts/figures/d4.png b/ETSUI/ShoppingEts/figures/d4.png new file mode 100644 index 0000000000000000000000000000000000000000..25873b3d177bb3d490c4a15daa7b09e37b70b68e Binary files /dev/null and b/ETSUI/ShoppingEts/figures/d4.png differ diff --git a/ETSUI/ShoppingEts/figures/d5.png b/ETSUI/ShoppingEts/figures/d5.png new file mode 100644 index 0000000000000000000000000000000000000000..6276426500fa113a6b0a0c3961d279f562735057 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/d5.png differ diff --git a/ETSUI/ShoppingEts/figures/mypage.png b/ETSUI/ShoppingEts/figures/mypage.png new file mode 100644 index 0000000000000000000000000000000000000000..7a21bec497c590f746cddb3c56eb6ace3fb19efb Binary files /dev/null and b/ETSUI/ShoppingEts/figures/mypage.png differ diff --git a/ETSUI/ShoppingEts/figures/shopca.png b/ETSUI/ShoppingEts/figures/shopca.png new file mode 100644 index 0000000000000000000000000000000000000000..02278bd7a396d0f18eb93f7ed3860ab219f2cf14 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/shopca.png differ diff --git a/ETSUI/ShoppingEts/figures/shopingCart2.png b/ETSUI/ShoppingEts/figures/shopingCart2.png new file mode 100644 index 0000000000000000000000000000000000000000..bea24f3f51574e3585714f0c6a0cbac3198ffdb8 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/shopingCart2.png differ diff --git a/ETSUI/ShoppingEts/figures/shoppingDetail1.png b/ETSUI/ShoppingEts/figures/shoppingDetail1.png new file mode 100644 index 0000000000000000000000000000000000000000..ea78acc224b2e4436f351693485e1ac941efbfc4 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/shoppingDetail1.png differ diff --git a/ETSUI/ShoppingEts/figures/shoppingDetail2.png b/ETSUI/ShoppingEts/figures/shoppingDetail2.png new file mode 100644 index 0000000000000000000000000000000000000000..8499766c7a99c011d0d0853e5fba456b3caa43b8 Binary files /dev/null and b/ETSUI/ShoppingEts/figures/shoppingDetail2.png differ diff --git "a/ETSUI/ShoppingEts/figures/\345\217\226\347\211\210\346\234\254.png" "b/ETSUI/ShoppingEts/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/ETSUI/ShoppingEts/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/ETSUI/ShoppingEts/figures/\346\210\252\345\233\276.png" "b/ETSUI/ShoppingEts/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/ETSUI/ShoppingEts/figures/\346\210\252\345\233\276.png" differ diff --git "a/ETSUI/ShoppingEts/figures/\346\226\260\345\273\272\351\241\265\351\235\242.png" "b/ETSUI/ShoppingEts/figures/\346\226\260\345\273\272\351\241\265\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..eda68f0fbfd3459ae29f9eb53dceb7de7afa3da4 Binary files /dev/null and "b/ETSUI/ShoppingEts/figures/\346\226\260\345\273\272\351\241\265\351\235\242.png" differ diff --git a/ETSUI/ShoppingEts/gradle/wrapper/gradle-wrapper.jar b/ETSUI/ShoppingEts/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9 Binary files /dev/null and b/ETSUI/ShoppingEts/gradle/wrapper/gradle-wrapper.jar differ diff --git a/ETSUI/ShoppingEts/gradle/wrapper/gradle-wrapper.properties b/ETSUI/ShoppingEts/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..f59159e865d4b59feb1b8c44b001f62fc5d58df4 --- /dev/null +++ b/ETSUI/ShoppingEts/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/ETSUI/ShoppingEts/public_sys-resources/icon-caution.gif b/ETSUI/ShoppingEts/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/ShoppingEts/public_sys-resources/icon-caution.gif differ diff --git a/ETSUI/ShoppingEts/public_sys-resources/icon-danger.gif b/ETSUI/ShoppingEts/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/ShoppingEts/public_sys-resources/icon-danger.gif differ diff --git a/ETSUI/ShoppingEts/public_sys-resources/icon-note.gif b/ETSUI/ShoppingEts/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/ETSUI/ShoppingEts/public_sys-resources/icon-note.gif differ diff --git a/ETSUI/ShoppingEts/public_sys-resources/icon-notice.gif b/ETSUI/ShoppingEts/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/ETSUI/ShoppingEts/public_sys-resources/icon-notice.gif differ diff --git a/ETSUI/ShoppingEts/public_sys-resources/icon-tip.gif b/ETSUI/ShoppingEts/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/ETSUI/ShoppingEts/public_sys-resources/icon-tip.gif differ diff --git a/ETSUI/ShoppingEts/public_sys-resources/icon-warning.gif b/ETSUI/ShoppingEts/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/ShoppingEts/public_sys-resources/icon-warning.gif differ diff --git a/ETSUI/ShoppingEts/settings.gradle b/ETSUI/ShoppingEts/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07 --- /dev/null +++ b/ETSUI/ShoppingEts/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/ETSUI/SimpleGalleryEts/LICENSE b/ETSUI/SimpleGalleryEts/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..80576ef141485b36eea4aebf25af97020bc2de44 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + + 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/README.md b/ETSUI/SimpleGalleryEts/README.md index 1586e959ede664d5e6d51c66ca6e914593515558..dd7c9afc00ef4801bb5280c0aa08c2b4da9538bd 100644 --- a/ETSUI/SimpleGalleryEts/README.md +++ b/ETSUI/SimpleGalleryEts/README.md @@ -1,2 +1,474 @@ -tmp +# 极简声明式UI范式 +# 介绍 + +- [应用场景](#section225718574575) + +## 应用场景 + +声明式UI开发框架,采用更接近自然语义的编程方式,让开发者可以直观地描述UI界面,不必关心框架如何实现UI绘制和渲染,从而实现极简高效的开发。从组件、动效和状态管理三个维度来提供UI能力,还提供了多端部署和系统能力接口,真正实现多端代码共享和系统能力的极简调用。 + +本篇Codelab使用极简声明式UI范式开发完成如下功能: + +- 组合系统组件为自定义组件,完成顶部标签栏、推荐栏。 +- 使用共享元素转场动画、显示动画完成大图浏览界面。 +- 使用状态数据管理完成组件之间的数据传递。 + +为了让您快速了解本篇Codelab所实现的功能,我们先对极简声明式UI范式开发进行展示,效果如下: + +![](figures/VID_20211222_162936-00_00_00-00_00_30-1.gif) + +# 相关概念 + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 代码结构解读 + +本篇Codelab只对核心代码进行讲解,以下介绍整个工程的代码结构。 + +![](figures/036C0734-B95E-4D50-98E1-BEEC33160D0E.png) + +- common:自定义组件。 + - bottomTabs.ets:底部页签容器。 + - homeListItem.ets:首页推荐列表项。 + - homeTabContent.ets:首页页签内容。 + - topTabs.ets:顶部标签。 + +- model:数据结构和数据初始化。 + - homeListDataModel.ets:今日推荐、精选推荐、X月推荐数据。 + +- pages:页面。 + - home.ets:首页。 + - image.ets:图片预览界面。 + +- resources:项目资源存放路径,包括图片资源和国际化字符串等。 +- config.json:应用的配置文件。 + +# 页面布局与搭建 + +- Tabs组件 + +- 推荐List布局 + +- 大图浏览界面布局 + +- 页面跳转和数据传递 + +# Tabs组件 + +在这一小节中,我们实现首页底部页签和顶部标签的布局。首先我们使用Flex组件,在Flex组件中使用Tabs组件。 + +1. 在common中创建文件bottomTabs.ets,自定义底部页签容器BottomTabs。使用ForEach语句,显示四个相同的页签,每个页签使用Column组件,使用justifyContent: FlexAlign.SpaceEvenly来使页签均分布局。 + + ![](figures/zh-cn_image_0000001237578411.png) + + ``` + import prompt from '@system.prompt' + + @Component + export struct BottomTabs { + private tabSrc: number[] = [0, 1, 2, 3] + @Link bottomTabIndex: number + + build() { + Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceEvenly }) { // FlexAlign.SpaceEvenly实现均分布局 + ForEach(this.tabSrc, item => { // 通过ForEach语句添加四个页签 + Column() { + Image(getTabSrc(this.bottomTabIndex, item)) + .objectFit(ImageFit.Contain) + ...... + } + }) + } + .width('100%') + .height('8%') + } + } + ``` + +2. Tabs组件中TabContent中的内容使用自定义组件完成,新建homeTabContent.ets文件,实现HomeTabComponent 组件。 + + ![](figures/zh-cn_image_0000001237778483.png) + + ``` + import { TopTabs } from '../common/topTabs' + + @Component + export struct HomeTabComponent { + private recommends: Resource[] = [$r('app.string.today_recommend'), + $r('app.string.featured_recommend'), + $r('app.string.september_recommend'), + $r('app.string.august_recommend')] + @Link showSettings: boolean + + build() { + Column() { + TopTabs({ showSettings: $showSettings }) // 自定义组件顶部标签 + ...... // 页面内容,此处省略 + } + } + } + ``` + +3. 首页中引用自定义组件显示。 + + ``` + import { HomeTabComponent } from '../common/homeTabContent' // import导入自定义组件 + + @Entry + @Component + struct HomeComponent { + build() { + Stack({ alignContent: Alignment.BottomStart }) { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.End, justifyContent: FlexAlign.End }) { + Tabs({ barPosition: BarPosition.End, controller: this.controller }) { + TabContent() { + HomeTabComponent({ showSettings: $showSettings }) // TabContent的内容使用自定义组件HomeTabComponent + } + .padding({ left: 15, right: 15 }) + } + .vertical(false) + .barHeight(0) // 本篇Codelab中使用了自定义的底部页签,不使用Tabs的TabBar,所以BarHeight为0 + .width('100%') + .scrollable(false) + } + BottomTabs({ controller: this.controller, bottomTabIndex: $bottomTabIndex }) // 底部页签容器组件 + } + .width('100%') + .height('100%') + } + } + ``` + +# 推荐List布局 + +首先,在首页中有今日推荐、精选推荐等推荐栏,在HomeTabComponent组件中,推荐栏放在List中作为List的ListItem组件显示。推荐列表使用ForEach语句,LisItem中使用自定义组件HomeListItem,在HomeListItem组件中会判断是否是今日推荐来获取不同的数据。 + +![](figures/zh-cn_image_0000001192938616.png) + +``` +import {TopTabs} from '../common/topTabs' +import {HomeListItem} from '../common/homeListItem' + +@Component +export struct HomeTabComponent { + private recommends: Resource[] = [$r('app.string.today_recommend'), $r('app.string.featured_recommend'), + $r('app.string.september_recommend'), $r('app.string.august_recommend')] + + build() { + Column() { + TopTabs() + List() { + ForEach(this.recommends, item => { + ListItem() { + HomeListItem({ titleIndex: this.recommends.indexOf(item) }) + } + }, item => this.recommends.indexOf(item).toString()) + } + .listDirection(Axis.Vertical) + .width('100%') + .layoutWeight(1) + } + } +} +``` + +然后,今日推荐、精选推荐等作为ListItem,使用自定义组件HomeListItem作为子组件,下面介绍自定义组件HomeListItem: + +1. 在common中创建homeListItem.ets作为自定义组件。 + + ![](figures/zh-cn_image_0000001237898779.png) + +2. HomeListItem中包括上面的title和下面图片列表两部分,使用ForEach语句显示图片列表。 + + ``` + @Component + export struct HomeListItem { + private recommends: Resource[] = [$r('app.string.today_recommend'), + $r('app.string.featured_recommend'), + $r('app.string.september_recommend'), + $r('app.string.august_recommend')] + private listItems: ImageData[] = initializeImageData() + private titleIndex: number = 0 + private imageWidth: string = '120' + private ratio: number = 1 + + build() { + Column() { + Row() { + Text(this.recommends[this.titleIndex]) // // 这里this.recommends[this.titleIndex]是推荐的title + .textAlign(TextAlign.Start) + .fontSize(16) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + .borderColor(Color.Blue) + } + .width('100%') + + List({ initialIndex: 0 }) { // 图片列表 + ForEach(this.listItems, item => { + ListItem() { + Image(item.smallImg) + .width(this.imageWidth) + .aspectRatio(this.ratio) + .borderRadius(10) + .margin({ right: 15 }) + } + }) + } + .listDirection(Axis.Horizontal) + .margin({ top: '2%', bottom: '2%' }) + } + } + } + ``` + + ![](figures/IMG_20211222_162835.jpg) + +# 大图浏览界面布局 + +点击首页推荐栏中的图片,可以进入大图浏览界面,现在来实现大图界面的布局。 + +1. 首先在pages文件夹中,单击右键,然后新建eTS Page,命名为 image.ets。 + + ![](figures/zh-cn_image_0000001237738855.png) + +2. 大图浏览界面从界面上分为顶部titleBar,底部toolBar,中间图片铺满屏幕。由于图片需要左右滑动切换,此处使用Swiper组件,Swiper中子组件使用Image。 + + ``` + import { ImageData, initializeImageData, initializeTodayData } from '../model/HomeListDataModel' + + @Entry + @Component + struct ImageComponent{ + private imageSrc: ImageData[] = initializeImageData() + private imageIndex: number = router.getParams().index + private title: string = '' + @State imageMargin: number = 56 + @State visibility: Visibility = Visibility.Visible + + build() { + Flex({ direction: FlexDirection.Column,alignItems: ItemAlign.End, justifyContent: FlexAlign.End }) { + Row() { + ...... // titleBar部分 + } + .width('100%') + .height(this.imageMargin) + .backgroundColor('#F1F3F5') + .visibility(this.visibility) + Swiper(){ // 中间大图显示,使用Swiper组件 + ForEach(this.imageSrc, item => { + Image(item.bigImg) // Image作为Swiper的子组件,显示图片 + .height('100%') + .width('100%') + .objectFit(ImageFit.Contain) + },item => item.toString()) + } + } + .width('100%') + .height('100%') + Column() { + ...... // 底部工具栏部分 + } + .width('100%') + } + .width('100%') + .height('100%') + } + } + ``` + +# 页面跳转和数据传递 + +本篇Codelab中,页面跳转即首页推荐栏中的图片跳转到大图界面和大图界面点击返回图标回到首页,数据传递包括父组件向子组件传递参数,双向传递以及页面之间数据传递。 + +- 页面跳转及页面间数据传递。 + + 点击首页推荐栏中的图片跳转到大图界面,在homeListItem.ets中的图片列表中给Image添加点击事件,通过页面路由router完成页面跳转和参数传递。 + + ``` + List({ initialIndex: 0 }) { + ForEach(this.listItems, item => { + ListItem() { + Image(item.smallImg) + .onClick(() => { + let shareIdStr = this.titleIndex + item.id + console.info('Item onClick' + shareIdStr) + router.push({ // 通过页面路由router完成页面跳转 + uri: 'pages/image', + params: { isToday: this.isToday, shareId: shareIdStr, index: item.id } // 参数传递 + }) + }) + } + }) + } + .listDirection(Axis.Horizontal) + .margin({ top: '2%', bottom: '2%' }) + ``` + + 大图界面使用router.getParams\(\)获取参数,实现返回图片的onClick事件,执行router.back\(\)来返回首页。 + + ``` + import router from '@system.router' + @Entry + @Component + struct Index { + // 获取参数 + private imageIndex: number = router.getParams().index + private shareId: string = router.getParams().shareId + private isToday: boolean = router.getParams().isToday + + build() { + Flex({ direction: FlexDirection.Column,alignItems: ItemAlign.End, justifyContent: FlexAlign.End }) { + Row() { + Image('/common/arrow.png') + .width('10%') + .height('80%') + .objectFit(ImageFit.Contain) + .margin({ left: 10 }) + .onClick(() => { + router.back() // 通过router.back()返回 + }) + } + } + .width('100%') + .height('100%') + } + } + ``` + +- 组件之间的数据传递。 + + - 父组件向子组件传递参数。 + + 自定义组件作为子组件,父组件引用时直接传递参数,子组件中定义参数即可。 + + ``` + //在homeTabContent.ets中引用自定义组件时直接传参数 + ForEach(this.recommends, item => { + ListItem() { + HomeListItem({ titleIndex: this.recommends.indexOf(item) }) + } + }, item => this.recommends.indexOf(item).toString()) + ``` + + ``` + //在homeListItem.ets中定义的子组件中定义参数 + @Component + export struct HomeListItem{ + private titleIndex: number = 0 + ...... + } + ``` + + - 父组件和子组件之间双向传递。 + + 父组件和子组件之间的双向传递使用状态数据管理,状态数据管理作为声明式UI的特色,通过功能不同的装饰器给开发者提供了清晰的页面更新渲染的流程和管道。状态管理包括UI组件状态和应用程序状态,两者协作可以使开发者完整地架构整个应用的数据更新和UI渲染。本篇Codelab中首页中的bottomTabIndex代表当前Tabs在第几页。双向传递父组件使用@State修饰的变量,子组件使用@Link修饰,且父组件需要使用$引用。 + + ``` + @Entry + @Component + struct HomeComponent { + @State bottomTabIndex: number = 0 // 父组件需要时@State修饰 + build() { + Stack({ alignContent: Alignment.BottomStart }) { + ...... + BottomTabs({ controller: this.controller, bottomTabIndex: $bottomTabIndex }) // 使用$引用传递数据 + }.width('100%').height('100%') + } + } + ``` + + ``` + @Component + export struct BottomTabs { + private tabSrc: number[] = [0, 1, 2, 3] + private backgroundColor: string = '#F1F3F5' + private controller: TabsController = new TabsController() + @Link bottomTabIndex: number // 子组件中使用@Link修饰 + ...... + } + ``` + + + +# 动画 + +- 添加共享元素转场动画。 + + 共享元素转场支持页面内的转场,如Row组件中的元素转场至List组件中;也支持页面间的转场,如当前页面的图片转场至下一页面中,只需要调用动画接口sharedTransition实现,使用非常简单。此处使用共享元素转场动画完成点击小图进入大图浏览界面和大图浏览界面返回的动画。两个页面的组件配置为同一个id,则转场过程中会进行共享元素转场,配置为空字符串时不会有共享元素转场效果。使用sharedTransition属性方法添加共享元素转场动画。 + + ``` + // 在首页的HomeListItem.ets中的图片ListItem中添加共享元素转场动画 + List({ initialIndex: 0 }) { + ForEach(this.listItems, item => { + ListItem() { + Image(item.smallImg) + .width(this.imageWidth) + .aspectRatio(this.ratio) + .borderRadius(10) + .margin({ right: 15 }) + .sharedTransition(this.titleIndex + item.id, { duration: 500, curve: Curve.Linear }) + } + }) + } + .listDirection(Axis.Horizontal) + .margin({ top: '2%', bottom: '2%' }) + ``` + + ``` + // 在image.ets加共享元素转场动画 + Swiper(){ + ForEach(this.imageSrc, item => { + Image(item.bigImg) + .height('100%') + .width('100%') + },item => item.toString()) + } + .width('100%') + .aspectRatio(this.ratio) + .scale({ x: this.scale, y: this.scale }) + .index(this.imageIndex) + .indicator(false) + .loop(false) + .sharedTransition(this.shareId, { duration: 500, curve: Curve.Linear }) + ``` + +# 恭喜你 + +目前你已经成功完成了Codelab并且学到了: + +- 如何通过极简声明式UI范式使用常用组件,包括Text、Image、 List、listItem、Tabs等。 +- 如何通过极简声明式UI范式完成自定义弹窗。 +- 如何通过极简声明式UI范式完成页面跳转及数据传递。 +- 如何通过极简声明式UI范式完成动画添加。 + +# 参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/SimpleGalleryEts) diff --git a/ETSUI/SimpleGalleryEts/build.gradle b/ETSUI/SimpleGalleryEts/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..8091e0ece10575993ba570722aadd6788144f460 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/build.gradle @@ -0,0 +1,34 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + supportSystem "standard" +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } + dependencies { + classpath 'com.huawei.ohos:hap:3.0.3.4' + classpath 'com.huawei.ohos:decctest:1.2.6.0' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } +} diff --git a/ETSUI/SimpleGalleryEts/entry/.gitignore b/ETSUI/SimpleGalleryEts/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7d5b7a94f4dcf381f03ff21f28f8a2494b58023f --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/.gitignore @@ -0,0 +1,2 @@ +/build +/node_modules diff --git a/ETSUI/SimpleGalleryEts/entry/build.gradle b/ETSUI/SimpleGalleryEts/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..1587dd1948941f3eaaf092ae6cae7969cb6895ff --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/build.gradle @@ -0,0 +1,21 @@ +apply plugin: 'com.huawei.ohos.hap' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + defaultConfig { + compatibleSdkVersion 7 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13.1' +} diff --git a/ETSUI/SimpleGalleryEts/entry/proguard-rules.pro b/ETSUI/SimpleGalleryEts/entry/proguard-rules.pro new file mode 100644 index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/config.json b/ETSUI/SimpleGalleryEts/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..e2ac41d23f256ffa2561c9fba2df242a3d20a045 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/config.json @@ -0,0 +1,67 @@ +{ + "app": { + "bundleName": "com.example.simplegalleryetsopenh", + "vendor": "example", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "com.example.simplegalleryetsopenh", + "name": ".MyApplication", + "mainAbility": ".MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "visible": true, + "srcPath": "MainAbility", + "name": ".MainAbility", + "srcLanguage": "ets", + "icon": "$media:icon", + "description": "$string:description_mainability", + "formsEnabled": false, + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "mode": { + "syntax": "ets", + "type": "pageAbility" + }, + "pages": [ + "pages/home", + "pages/image" + ], + "name": ".MainAbility", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/app.ets b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..b7a0995c8e441cac86e21e06e7c9071664482b1c --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/app.ets @@ -0,0 +1,8 @@ +export default { + onCreate() { + console.info('Application onCreate') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/bottomTabs.ets b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/bottomTabs.ets new file mode 100644 index 0000000000000000000000000000000000000000..704d3003e158a9192e64ec28f833e6de045825ab --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/bottomTabs.ets @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 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 prompt from '@system.prompt' + +function getTabSrc(tabIndex: number, index: number) { + let imgSrc = $r('app.media.tab_gray') + if (tabIndex === index) { + imgSrc = $r('app.media.tab_blue') + } + return imgSrc +} + +function getTabTextColor(tabIndex: number, index: number) { + let color = '#000000' + if (tabIndex === index) { + color = '#0A59F7' + } + return color +} + +@Component +export struct BottomTabs { + private tabSrc: number[] = [0, 1, 2, 3] + private backgroundColor: string = '#F1F3F5' + private controller: TabsController = new TabsController() + private tips: string = '这是测试功能,暂时未实现' + @Link bottomTabIndex: number + + build() { + Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceEvenly }) { + ForEach(this.tabSrc, item => { + Column() { + Image(getTabSrc(this.bottomTabIndex, item)) + .objectFit(ImageFit.Contain) + .width('60%').height('60%') + Text($r('app.string.tab_strings')) + .fontSize(14) + .fontColor(getTabTextColor(this.bottomTabIndex, item)) + } + .onClick(() => { + if (item === this.bottomTabIndex) { + this.controller.changeIndex(this.bottomTabIndex) + } else { + prompt.showToast({ + message: this.tips + }) + } + }) + }, item => item.toString()) + } + .width('100%').height('8%') + .backgroundColor(this.backgroundColor) + } +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/homeListItem.ets b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/homeListItem.ets new file mode 100644 index 0000000000000000000000000000000000000000..167eba58f3fe127a6b0bed098687978def37c5fd --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/homeListItem.ets @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 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 router from '@system.router' +import { ImageData, initializeImageData, initializeTodayData } from '../model/homeListDataModel' + +@Component +export struct HomeListItem { + private recommends: Resource[] = [$r('app.string.today_recommend'), $r('app.string.featured_recommend'), + $r('app.string.september_recommend'), $r('app.string.august_recommend')] + private listItems: ImageData[] = initializeImageData() + private isToday: boolean = true + private titleIndex: number = 0 + private imageWidth: string = '120' + private ratio: number = 1 + + aboutToAppear() { + if (this.titleIndex === 0) { + this.listItems = initializeTodayData() + this.isToday = true + this.imageWidth = '92' + this.ratio = 1 + } else { + this.listItems = initializeImageData() + this.isToday = false + this.imageWidth = '145' + this.ratio = 0.65 + } + } + + build() { + Column() { + Row() { + Text(this.recommends[this.titleIndex]) + .textAlign(TextAlign.Start) + .fontSize(16) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + .borderColor(Color.Blue) + Text($r('app.string.more')) + .fontSize(16) + .fontColor(Color.Gray) + Image($r('app.media.more')) + .width('10').height('5%') + .alignSelf(ItemAlign.End) + .objectFit(ImageFit.Contain) + } + .width('100%') + + List({ initialIndex: 0 }) { + ForEach(this.listItems, item => { + ListItem() { + Image(item.smallImg) + .width(this.imageWidth) + .aspectRatio(this.ratio) + .borderRadius(10) + .margin({ right: 15 }) + .sharedTransition(this.titleIndex + item.id, { duration: 500, curve: Curve.Linear }) + .onClick(() => { + let shareIdStr = this.titleIndex + item.id + console.info('Item onClick' + shareIdStr) + router.push({ + uri: 'pages/image', + params: { isToday: this.isToday, shareId: shareIdStr, index: item.id, ratio: this.ratio } + }) + }) + } + }, item => item.name) + } + .listDirection(Axis.Horizontal) + .margin({ top: '2%', bottom: '2%' }) + } + } +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/homeTabContent.ets b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/homeTabContent.ets new file mode 100644 index 0000000000000000000000000000000000000000..41c9fb2df892fdc64df87ef42b8b77edb8682dfb --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/homeTabContent.ets @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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 { TopTabs } from '../common/topTabs' +import { HomeListItem } from '../common/homeListItem' + +@Component +export struct HomeTabComponent { + private recommends: Resource[] = [$r('app.string.today_recommend'), $r('app.string.featured_recommend'), + $r('app.string.september_recommend'), $r('app.string.august_recommend')] + + + build() { + Column() { + TopTabs() + List() { + ForEach(this.recommends, item => { + ListItem() { + HomeListItem({ titleIndex: this.recommends.indexOf(item) }) + } + }, item => this.recommends.indexOf(item).toString()) + } + .listDirection(Axis.Vertical) + .width('100%') + .layoutWeight(1) + } + } +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/topTabs.ets b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/topTabs.ets new file mode 100644 index 0000000000000000000000000000000000000000..b33eabf177dcb6672acbd0c950d91115f50a6a98 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/common/topTabs.ets @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 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 prompt from '@system.prompt' + +@Component +export struct TopTabs { + private tabs: Resource[] = [$r('app.string.featured'), $r('app.string.discover'), $r('app.string.wallpaper'), + $r('app.string.knowledge'), $r('app.string.photo')] + + private tips: string = '这是测试功能,暂时未实现' + + + build() { + Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) { + Row() { + ForEach(this.tabs, item => { + if (this.tabs.indexOf(item) == 0) { + Text(item) + .fontSize(18) + .fontWeight(FontWeight.Bold) + } else { + Text(item) + .fontSize(17) + .fontWeight(FontWeight.Medium) + .margin({ left: '5%' }) + } + }, item => this.tabs.indexOf(item).toString()) + } + .layoutWeight(1) + .height('100%') + + Image($r('app.media.search')) + .width('7%').height('80%') + .constraintSize({ maxWidth: 25 }) + .objectFit(ImageFit.Contain) + .onClick(() => { + prompt.showToast({ + message: this.tips + }) + }) + } + .height('8%').width('100%') + .alignSelf(ItemAlign.Start) + } +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/model/homeListDataModel.ets b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/model/homeListDataModel.ets new file mode 100644 index 0000000000000000000000000000000000000000..af19e5bdea039756f43677cc9b2e25ca64d7f139 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/model/homeListDataModel.ets @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 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 ImageData { + id: string + smallImg: Resource + bigImg: Resource + name: string + + constructor(id: string, smallImg: Resource, bigImg: Resource, name: string) { + this.id = id + this.smallImg = smallImg + this.bigImg = bigImg + this.name = name + } +} + +export function initializeImageData(): Array { + let imageDataArray: Array = [ + { "id": "0", "smallImg": $r('app.media.recommend1'), "bigImg": $r('app.media.recommend1'), "name": '推荐1' }, + { "id": "1", "smallImg": $r('app.media.recommend2'), "bigImg": $r('app.media.recommend2'), "name": '推荐2' }, + { "id": "2", "smallImg": $r('app.media.recommend3'), "bigImg": $r('app.media.recommend3'), "name": '推荐3' }, + { "id": "3", "smallImg": $r('app.media.recommend4'), "bigImg": $r('app.media.recommend4'), "name": '推荐4' }, + { "id": "4", "smallImg": $r('app.media.recommend5'), "bigImg": $r('app.media.recommend5'), "name": '推荐5' }, + { "id": "5", "smallImg": $r('app.media.recommend6'), "bigImg": $r('app.media.recommend6'), "name": '推荐6' }, + { "id": "6", "smallImg": $r('app.media.recommend7'), "bigImg": $r('app.media.recommend7'), "name": '推荐7' }, + ] + return imageDataArray +} + +export function initializeTodayData(): Array { + let todyDataArray: Array = [ + { "id": "0", "smallImg": $r('app.media.today1'), "bigImg": $r('app.media.today1'), "name": '今日推荐1' }, + { "id": "1", "smallImg": $r('app.media.today2'), "bigImg": $r('app.media.today2'), "name": '今日推荐2' }, + { "id": "2", "smallImg": $r('app.media.today3'), "bigImg": $r('app.media.today3'), "name": '今日推荐3' }, + { "id": "3", "smallImg": $r('app.media.today4'), "bigImg": $r('app.media.today4'), "name": '今日推荐4' }, + { "id": "4", "smallImg": $r('app.media.today5'), "bigImg": $r('app.media.today5'), "name": '今日推荐5' }, + { "id": "5", "smallImg": $r('app.media.today6'), "bigImg": $r('app.media.today6'), "name": '今日推荐6' }, + { "id": "6", "smallImg": $r('app.media.today7'), "bigImg": $r('app.media.today7'), "name": '今日推荐7' }, + { "id": "7", "smallImg": $r('app.media.today8'), "bigImg": $r('app.media.today8'), "name": '今日推荐8' }, + { "id": "8", "smallImg": $r('app.media.today9'), "bigImg": $r('app.media.today9'), "name": '今日推荐9' }, + { "id": "9", "smallImg": $r('app.media.today10'), "bigImg": $r('app.media.today10'), "name": '今日推荐10' }, + { "id": "10", "smallImg": $r('app.media.today11'), "bigImg": $r('app.media.today11'), "name": '今日推荐11' } + ] + return todyDataArray +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/pages/home.ets b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/pages/home.ets new file mode 100644 index 0000000000000000000000000000000000000000..96cdcdec7327daee5a3e3b60f79ecca7aa38a1c5 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/pages/home.ets @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 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 {HomeTabComponent} from '../common/homeTabContent' +import {BottomTabs} from '../common/bottomTabs' + +@Entry +@Component +struct HomeComponent { + private controller: TabsController = new TabsController() + private backgroundColor: string = '#F1F3F5' + @State bottomTabIndex: number = 0 + + build() { + Stack({ alignContent: Alignment.BottomStart }) { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.End, justifyContent: FlexAlign.End }) { + Tabs({ barPosition: BarPosition.End, index: 0, controller: this.controller }) { + TabContent() { + HomeTabComponent() + }.padding({ left: 15, right: 15 }) + + TabContent() { + } + + TabContent() { + } + + TabContent() { + } + } + .onChange((index: number) => { + this.bottomTabIndex = index + }) + .vertical(false) + .barHeight(0) + .width('100%') + .scrollable(false) + + BottomTabs({ controller: this.controller, bottomTabIndex: $bottomTabIndex }) + } + .width('100%') + .layoutWeight(1) + .backgroundColor(this.backgroundColor) + } + .width('100%').height('100%') + } +} diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/pages/image.ets b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/pages/image.ets new file mode 100644 index 0000000000000000000000000000000000000000..d49e6c678fbe16ac7ba3cf660e62426fbfcd9530 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/ets/MainAbility/pages/image.ets @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2021 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 router from '@system.router' +import {ImageData, initializeImageData, initializeTodayData} from '../model/homeListDataModel' + +@Entry +@Component +struct ImageComponent { + private imageSrc: ImageData[] = initializeImageData() + private imageIndex: number = router.getParams().index + private shareId: string = router.getParams().shareId + private isToday: boolean = router.getParams().isToday + @State ratio: number = router.getParams().ratio + @State title: string = '' + @State imageMargin: number = 56 + @State visibility: Visibility = Visibility.Visible + @State scale: number = 1 + + aboutToAppear() { + if (this.isToday) { + this.imageSrc = initializeTodayData() + } else { + this.imageSrc = initializeImageData() + } + if(this.imageIndex < this.imageSrc.length) { + this.title = this.imageSrc[this.imageIndex].name + } + + setTimeout(()=>{ + this.ratio = 0 + },500) + } + + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.End, justifyContent: FlexAlign.End }) { + Row() { + Image($r('app.media.arrow')) + .width('8%').height('50%') + .objectFit(ImageFit.Contain) + .margin({ left: 10 }) + .onClick(() => { + router.back() + }) + Text(this.title) + .fontSize(20) + .fontColor(Color.Black) + .margin({ left: 10 }) + } + .width('100%').height(this.imageMargin) + .backgroundColor('#F1F3F5') + .visibility(this.visibility) + + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Swiper() { + ForEach(this.imageSrc, item => { + Image(item.bigImg) + .height('100%').width('100%') + .objectFit(ImageFit.Contain) + .onClick(() => { + console.info('Image Click') + this.scale = 1 + if (this.visibility == Visibility.Hidden) { + this.imageMargin = 56 + this.visibility = Visibility.Visible + } else { + this.imageMargin = 0 + this.visibility = Visibility.Hidden + } + }) + .gesture( + GestureGroup(GestureMode.Parallel, + PinchGesture() + .onActionStart(() => { + console.log('pinch start') + }) + .onActionUpdate((event: GestureEvent) => { + if (this.visibility == Visibility.Hidden && event.scale <= 2.0) { + this.scale = event.scale + } + }) + .onActionEnd(() => { + if (this.scale < 1.0) { + animateTo({ duration: 500, curve: Curve.Ease }, () => { + this.scale = 1.0 + }) + } + }) + , TapGesture({ count: 2, fingers: 1 }) + .onAction(() => { + if (this.visibility == Visibility.Hidden) { + animateTo({ duration: 500, curve: Curve.Ease }, () => { + this.scale = this.scale < 2.0 ? 2.0 : 1.0 + }) + } + }) + ) + ) + }, item => item.name) + } + .width('100%').height('100%') + .aspectRatio(this.ratio) + .scale({ x: this.scale, y: this.scale }) + .index(this.imageIndex) + .indicator(false) + .loop(false) + .sharedTransition(this.shareId, { duration: 500, curve: Curve.Linear }) + .onChange((index: number) => { + this.scale = 1.0 + this.imageIndex = index + if(this.imageIndex < this.imageSrc.length) { + this.title = this.imageSrc[this.imageIndex].name + } + }) + }.width('100%').height('100%') + + Column() { + Image($r('app.media.delete')) + .objectFit(ImageFit.Contain) + .width(25).height(25) + .margin({ top: 5 }) + Text($r('app.string.delete')) + .fontSize(14) + .fontColor(Color.Black) + .textAlign(TextAlign.Start) + } + .width('100%').height(this.imageMargin) + .backgroundColor('#F1F3F5') + .visibility(this.visibility) + } + .width('100%').height('100%') + } +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/element/string.json b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..80d28f0c16810e0bce680a69448d8fe5d64801c0 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/element/string.json @@ -0,0 +1,96 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "SimpleGallery" + }, + { + "name": "mainability_description", + "value": "Simple_Gallery_Ability" + }, + { + "name": "tips", + "value": "This is a test function and has not been implemented." + }, + { + "name": "tab_strings", + "value": "Tab" + }, + { + "name": "featured", + "value": "featured" + }, + { + "name": "discover", + "value": "discover" + }, + { + "name": "wallpaper", + "value": "wallpaper" + }, + { + "name": "knowledge", + "value": "knowledge" + }, + { + "name": "photo", + "value": "photo" + }, + { + "name": "more", + "value": "more" + }, + { + "name": "delete", + "value": "delete" + }, + { + "name": "today_recommend", + "value": "Today Recommends" + }, + { + "name": "featured_recommend", + "value": "Featured Recommends" + }, + { + "name": "september_recommend", + "value": "September Recommends" + }, + { + "name": "august_recommend", + "value": "August Recommends" + }, + { + "name": "notification_settings", + "value": "Notification Settings" + }, + { + "name": "harmony_notification", + "value": "HarmonyOS Notification" + }, + { + "name": "background_reminderAgent", + "value": "HarmonyOS Background ReminderAgent" + }, + { + "name": "reminder_tips", + "value": "After the setting, the system clears the app, restarts the device, and shuts down the device. The notification is triggered normally." + }, + { + "name": "subscribe_succeed", + "value": "Subscribe succeed." + }, + { + "name": "add_reminder", + "value": "Do you want to add to the HarmonyOS background reminder?" + }, + { + "name": "yes", + "value": "Yes" + }, + { + "name": "no", + "value": "No" + } + ] +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/arrow.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..24513e54f3119d8e91d922108086afe8a5f766d3 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/arrow.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/close.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/close.png new file mode 100644 index 0000000000000000000000000000000000000000..4c7a6b6a3ade46a7754330a726fa3bd04c29f8e4 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/close.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/close_white.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/close_white.png new file mode 100644 index 0000000000000000000000000000000000000000..ec0c15ff0305c38df600447e7c2ba3d5da988b83 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/close_white.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/delete.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..8ad06f881d9e4aec1de46037679378252909548f Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/delete.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/icon.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/icon.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt1.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt1.png new file mode 100644 index 0000000000000000000000000000000000000000..408057b38163cdc5d9dc360014717e2dcc744cff Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt1.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt2.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt2.png new file mode 100644 index 0000000000000000000000000000000000000000..e136d552c3ea57088ea911d122a876819741234f Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt2.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt3.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt3.png new file mode 100644 index 0000000000000000000000000000000000000000..34690f9986b41c3f1b479d8472ffd512fcb6a927 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt3.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt4.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt4.png new file mode 100644 index 0000000000000000000000000000000000000000..edfa1afc4b5fd4a7e96e057f3b6a1b7c1f936966 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/jxdt4.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/more.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/more.png new file mode 100644 index 0000000000000000000000000000000000000000..4e361e699556a5b5ccae46dff999498baee96538 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/more.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend1.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend1.png new file mode 100644 index 0000000000000000000000000000000000000000..ebb003623e4ab60b180f54b12ced7520f62bc723 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend1.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend2.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend2.png new file mode 100644 index 0000000000000000000000000000000000000000..97f16b5fe63bd560c53988a0f6a07b8c6708e010 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend2.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend3.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend3.png new file mode 100644 index 0000000000000000000000000000000000000000..cd31df038600918012be012f520f4a0b2af47022 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend3.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend4.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend4.png new file mode 100644 index 0000000000000000000000000000000000000000..00cc73f4cc0331b59682045f4137d8f168aec8f5 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend4.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend5.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend5.png new file mode 100644 index 0000000000000000000000000000000000000000..a0fcc49852e8d6e6e9daad638884a41d94e0f3dc Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend5.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend6.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend6.png new file mode 100644 index 0000000000000000000000000000000000000000..0ca15c77deb161b1881eef9a0806ffdc45e8b7d2 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend6.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend7.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend7.png new file mode 100644 index 0000000000000000000000000000000000000000..c880ab0c9c4e009512fc521730159e5bef27d840 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/recommend7.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/search.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/search.png new file mode 100644 index 0000000000000000000000000000000000000000..68db577dc6b6e66a7e1784946175b2b5ce5499bd Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/search.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/setting.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/setting.png new file mode 100644 index 0000000000000000000000000000000000000000..5dd1d3d9d176380abdbd23afd0fe1e1dc2fe425c Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/setting.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/tab_blue.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/tab_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..c0882ba31589e41a902a0ed31075f8c55527129c Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/tab_blue.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/tab_gray.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/tab_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..32b626cf1e7da20c1cf8a45fc60727132ce0df2f Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/tab_gray.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today1.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today1.png new file mode 100644 index 0000000000000000000000000000000000000000..0ac6a72df85e065a8370ad408190109efa7865eb Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today1.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today10.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today10.png new file mode 100644 index 0000000000000000000000000000000000000000..0c63fee7fcbdce1f06eed0a11d49e83b68384a7d Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today10.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today11.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today11.png new file mode 100644 index 0000000000000000000000000000000000000000..75839f1e6626cd3623b204aa01029a6677be5589 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today11.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today2.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today2.png new file mode 100644 index 0000000000000000000000000000000000000000..f4657834613751d940341607854a3fb9dc7c19b2 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today2.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today3.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today3.png new file mode 100644 index 0000000000000000000000000000000000000000..50c2c40f5db6d726ac9a739ce4cc5894f7f3b7a4 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today3.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today4.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today4.png new file mode 100644 index 0000000000000000000000000000000000000000..363167853b7e47c81a929c2eff02dfe310488bfd Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today4.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today5.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today5.png new file mode 100644 index 0000000000000000000000000000000000000000..3b214b21626640fa4cf61fd3ec5796153d0e2e4d Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today5.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today6.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today6.png new file mode 100644 index 0000000000000000000000000000000000000000..48d48a42818b15ac3b8233ddb96c6146a8ed765d Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today6.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today7.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today7.png new file mode 100644 index 0000000000000000000000000000000000000000..759cbae649902badb8c8764769aa754ae407fd01 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today7.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today8.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today8.png new file mode 100644 index 0000000000000000000000000000000000000000..f082b0bfb20e6f7ca780609c5d6419b177bfe77c Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today8.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today9.png b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today9.png new file mode 100644 index 0000000000000000000000000000000000000000..f8d68d02c5fa6aa7c1f0c44a74d3791dd332bce4 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/entry/src/main/resources/base/media/today9.png differ diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/en/element/string.json b/ETSUI/SimpleGalleryEts/entry/src/main/resources/en/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..5857634212ce578c929519e20004371910423915 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/resources/en/element/string.json @@ -0,0 +1,96 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "SimpleGallery" + }, + { + "name": "mainability_description", + "value": "ETS_Empty Feature Ability" + }, + { + "name": "tips", + "value": "This is a test function and has not been implemented." + }, + { + "name": "tab_strings", + "value": "Tab" + }, + { + "name": "featured", + "value": "featured" + }, + { + "name": "discover", + "value": "discover" + }, + { + "name": "wallpaper", + "value": "wallpaper" + }, + { + "name": "knowledge", + "value": "knowledge" + }, + { + "name": "photo", + "value": "photo" + }, + { + "name": "more", + "value": "more" + }, + { + "name": "delete", + "value": "delete" + }, + { + "name": "today_recommend", + "value": "Today Recommends" + }, + { + "name": "featured_recommend", + "value": "Featured Recommends" + }, + { + "name": "september_recommend", + "value": "September Recommends" + }, + { + "name": "august_recommend", + "value": "August Recommends" + }, + { + "name": "notification_settings", + "value": "Notification Settings" + }, + { + "name": "harmony_notification", + "value": "HarmonyOS Notification" + }, + { + "name": "background_reminderAgent", + "value": "HarmonyOS Background ReminderAgent" + }, + { + "name": "reminder_tips", + "value": "After the setting, the system clears the app, restarts the device, and shuts down the device. The notification is triggered normally." + }, + { + "name": "subscribe_succeed", + "value": "Subscribe succeed." + }, + { + "name": "add_reminder", + "value": "Do you want to add to the HarmonyOS background reminder?" + }, + { + "name": "yes", + "value": "Yes" + }, + { + "name": "no", + "value": "No" + } + ] +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/rawfile/string.json b/ETSUI/SimpleGalleryEts/entry/src/main/resources/rawfile/string.json new file mode 100644 index 0000000000000000000000000000000000000000..0951821113958ff9f2fe8ea115edf3eb808035e7 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/resources/rawfile/string.json @@ -0,0 +1,5 @@ +{ + "strings": { + "test_tips": "这是测试功能,暂时还未实现." + } +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/entry/src/main/resources/zh/element/string.json b/ETSUI/SimpleGalleryEts/entry/src/main/resources/zh/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..042ddea66a52b629892b63e5e2b7bfd00948dd05 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/entry/src/main/resources/zh/element/string.json @@ -0,0 +1,96 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "简单图库" + }, + { + "name": "mainability_description", + "value": "简单图库能力" + }, + { + "name": "tab_strings", + "value": "页签" + }, + { + "name": "tips", + "value": "这是测试功能,暂时还未实现." + }, + { + "name": "featured", + "value": "精选" + }, + { + "name": "discover", + "value": "发现" + }, + { + "name": "wallpaper", + "value": "壁纸" + }, + { + "name": "knowledge", + "value": "知识" + }, + { + "name": "photo", + "value": "摄影" + }, + { + "name": "more", + "value": "更多" + }, + { + "name": "delete", + "value": "删除" + }, + { + "name": "today_recommend", + "value": "今日推荐" + }, + { + "name": "featured_recommend", + "value": "精选推荐" + }, + { + "name": "september_recommend", + "value": "9月推荐" + }, + { + "name": "august_recommend", + "value": "8月推荐" + }, + { + "name": "notification_settings", + "value": "通知设置" + }, + { + "name": "harmony_notification", + "value": "鸿蒙系统提醒" + }, + { + "name": "background_reminderAgent", + "value": "HarmonyOS后台代理提醒" + }, + { + "name": "reminder_tips", + "value": "设置后,清除应用、重启设备、设备关机,提醒正常触发" + }, + { + "name": "subscribe_succeed", + "value": "预定成功。" + }, + { + "name": "add_reminder", + "value": "是否添加到HarmonyOS后台代理提醒?" + }, + { + "name": "yes", + "value": "是" + }, + { + "name": "no", + "value": "否" + } + ] +} \ No newline at end of file diff --git a/ETSUI/SimpleGalleryEts/figures/036C0734-B95E-4D50-98E1-BEEC33160D0E.png b/ETSUI/SimpleGalleryEts/figures/036C0734-B95E-4D50-98E1-BEEC33160D0E.png new file mode 100644 index 0000000000000000000000000000000000000000..092e5bd3c895389454ca2d8203ccf5a5a4d832e4 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/figures/036C0734-B95E-4D50-98E1-BEEC33160D0E.png differ diff --git a/ETSUI/SimpleGalleryEts/figures/IMG_20211222_162835.jpg b/ETSUI/SimpleGalleryEts/figures/IMG_20211222_162835.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b6b98a85a7dffbdf59c438fbb91b3cc92ec2d7c4 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/figures/IMG_20211222_162835.jpg differ diff --git a/ETSUI/SimpleGalleryEts/figures/VID_20211222_162936-00_00_00-00_00_30-1.gif b/ETSUI/SimpleGalleryEts/figures/VID_20211222_162936-00_00_00-00_00_30-1.gif new file mode 100644 index 0000000000000000000000000000000000000000..d771e7630f4617e2c8581d796d3f0622d904d1f8 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/figures/VID_20211222_162936-00_00_00-00_00_30-1.gif differ diff --git a/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001192938616.png b/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001192938616.png new file mode 100644 index 0000000000000000000000000000000000000000..dc1666d07a37e19d231e3ecffabd51ab1784653d Binary files /dev/null and b/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001192938616.png differ diff --git a/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237578411.png b/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237578411.png new file mode 100644 index 0000000000000000000000000000000000000000..312229e1f156e70f852b21cfd3dd9c686181ea72 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237578411.png differ diff --git a/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237738855.png b/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237738855.png new file mode 100644 index 0000000000000000000000000000000000000000..f07a7a04741b2c7478602aa2614946ba8a290fcc Binary files /dev/null and b/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237738855.png differ diff --git a/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237778483.png b/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237778483.png new file mode 100644 index 0000000000000000000000000000000000000000..dc1666d07a37e19d231e3ecffabd51ab1784653d Binary files /dev/null and b/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237778483.png differ diff --git a/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237898779.png b/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237898779.png new file mode 100644 index 0000000000000000000000000000000000000000..e26c0032eaddb055a214782ad5e070c8befea9bf Binary files /dev/null and b/ETSUI/SimpleGalleryEts/figures/zh-cn_image_0000001237898779.png differ diff --git "a/ETSUI/SimpleGalleryEts/figures/\345\217\226\347\211\210\346\234\254.png" "b/ETSUI/SimpleGalleryEts/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/ETSUI/SimpleGalleryEts/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/ETSUI/SimpleGalleryEts/figures/\346\210\252\345\233\276.png" "b/ETSUI/SimpleGalleryEts/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/ETSUI/SimpleGalleryEts/figures/\346\210\252\345\233\276.png" differ diff --git a/ETSUI/SimpleGalleryEts/gradle/wrapper/gradle-wrapper.jar b/ETSUI/SimpleGalleryEts/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/gradle/wrapper/gradle-wrapper.jar differ diff --git a/ETSUI/SimpleGalleryEts/gradle/wrapper/gradle-wrapper.properties b/ETSUI/SimpleGalleryEts/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..f59159e865d4b59feb1b8c44b001f62fc5d58df4 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/ETSUI/SimpleGalleryEts/public_sys-resources/icon-caution.gif b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-caution.gif differ diff --git a/ETSUI/SimpleGalleryEts/public_sys-resources/icon-danger.gif b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-danger.gif differ diff --git a/ETSUI/SimpleGalleryEts/public_sys-resources/icon-note.gif b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-note.gif differ diff --git a/ETSUI/SimpleGalleryEts/public_sys-resources/icon-notice.gif b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-notice.gif differ diff --git a/ETSUI/SimpleGalleryEts/public_sys-resources/icon-tip.gif b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-tip.gif differ diff --git a/ETSUI/SimpleGalleryEts/public_sys-resources/icon-warning.gif b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/SimpleGalleryEts/public_sys-resources/icon-warning.gif differ diff --git a/ETSUI/SimpleGalleryEts/settings.gradle b/ETSUI/SimpleGalleryEts/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07 --- /dev/null +++ b/ETSUI/SimpleGalleryEts/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/ETSUI/SliderApplicationEts/LICENSE b/ETSUI/SliderApplicationEts/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..80576ef141485b36eea4aebf25af97020bc2de44 --- /dev/null +++ b/ETSUI/SliderApplicationEts/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + + 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/ETSUI/SliderApplicationEts/README.md b/ETSUI/SliderApplicationEts/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fd45c42deada242521e9bb3223d461c097ce4fb5 --- /dev/null +++ b/ETSUI/SliderApplicationEts/README.md @@ -0,0 +1,222 @@ +# SliderApplicationEts +# 介绍 + +- [应用场景](#section225718574575) + +## 应用场景 + +OpenHarmony eTS提供了丰富的接口和组件,开发者可以根据实际场景和开发需求,选用不同的组件和接口。在本教程中,我们将通过一个简单的样例,学习如何使用eTS开发框架的基础组件。本篇Codelab将会使用Image组件、Slider组件、Text组件共同实现一个可调节的风车动画,完成效果如下图所示: + +![](figures/zh-cn_image_0000001189625832.gif) + +# 相关概念 + +- [eTS工程目录](#section116501561575) + +**Text组件**:文本组件,用于呈现一段信息。 + +**Image组件**:图片组件,用来渲染展示图片。 + +**Slider组件**:滑动条组件,用来快速调节设置值,如音量、亮度等。 + +## eTS工程目录 + +新建工程的ETS目录如下图所示。 + +![](figures/zh-cn_image_0000001190968020.png) + +**各个文件夹和文件的作用:** + +- **index.ets**:用于描述UI布局、样式、事件交互和页面逻辑。 +- **app.ets**:用于全局应用逻辑和应用生命周期管理。 +- **pages**:用于存放所有组件页面。 +- **resources**:用于存放资源配置文件。 + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 任务一:如何让风车动起来 + +整个程序的页面构造十分简洁,由Image组件构成风车,Text组件和Slider组件构成文本显示和图像控制,具体效果如下图所示: + +![](figures/zh-cn_other_0000001190624180.jpeg) + +将代码写在默认文件index.ets中。整个页面使用了一个Image组件、两个Text组件、两个Slider组件。整个布局由上到下,呈线性排列。 + +首先使用Image组件填充页面上半部分,删掉默认代码中的Text组件,添加Image组件,给定使用图片的路径,并通过“.”运算符链式调用为组件配置多个属性。由于整个页面布局呈线性排列,所以需要将默认的Flex更换为Column,同时也将本工程使用到的参数一并声明给出,参数具体代码如下: + +``` +@Entry +@Component +struct Index { + @State private speed: number = 5 + @State private imageSize: number = 1 + @State private angle: number = 0 + @State private interval: number = 0 + + build() { + Column() { + Row() { + Image($r('app.media.windmill')) + .objectFit(ImageFit.Contain) + .height(150) + .width(150) + .position({ x: 110, y: 100 }) + .rotate({ x: 0, y: 0, z: 1, angle: this.angle }) + .scale({ x: this.imageSize, y: this.imageSize }) + } + .width(375) + .height(375) + } + .margin({ left: 30, right: 30 }) + } +} +``` + +将工程中使用到的图片,添加到**resources -\> base -\> media**目录下。 + +![](figures/zh-cn_image_0000001190942198.png) + +那么如何让风车动起来呢 ,这里就要用到组件通用属性中的图形变换,给Image组件配置了rotate属性和scale属性,其具体的含义如下表: + + + + + + + + + + + + + + + + + + + + +

名称

+

参数类型

+

默认值

+

描述

+

rotate

+

{x?: Angle, y?: Angle, z?: Angle, centerX?: Length, centerY?: Length}

+

{x: 0, y: 0, z: 0}

+

可以分别设置绕X轴、Y轴、Z轴的旋转角度,正角度为顺时针转动,负角度为逆时针转动,默认值为0,同时可以通过centerX和centerY设置旋转的中心点。

+

scale

+

{x?: number, y?: number, z?: number, centerX?: Length, centerY?: Length}

+

{x: 1, y: 1, z: 1}

+

可以分别设置X轴、Y轴、Z轴的缩放比例,默认值为1,同时可以通过centerX和centerY设置缩放的中心点。

+
+ + +所以要想使风车转起来,我们只需要在应用启动的时候,以固定的时间间隔调整rotate的角度也就是参数angle,接下来和build\(\)同级,继续添加如下方法: + +``` +speedChange() { + var that = this; + that.angle = 0; + this.interval = setInterval(function () { + that.angle += that.speed + }, 15 ) +} + +onPageShow() { + clearInterval(this.interval) + this.speedChange() +} +``` + +其中onPageShow是生命周期方法,表示从程序启动时,便开始执行。自此我们已经实现了风车的旋转效果。 + +# 任务二:调节风车的转速和大小 + +在这个任务中,我们将一起实现风车的转速和大小的调节。为了实现此效果我们需要用到Slider组件进行滑动调节,并且将数据实时显示在Text组件上。我们发现每个Text组件只有显示的内容不一样,组件的属性是一致的。所以我们使用自定义构造函数@Builder简化代码,和build\(\)同级有如下代码: + +``` +@Builder DescribeText(text:string, speed: number) { + Stack() { + Text(text + speed.toFixed(1)) + .margin({ top: 30 }) + .fontSize(20) + .fontWeight(FontWeight.Bold) + } +} +``` + +接下来结合Slider组件,实现调节风车的效果。首先实现速度的调节,在Slider的构造参数中,给定初始值和样式。在onChange事件中,将滑动的value给到事先定义好的变量speed,实现Text组件的更新,并且通过调用speedChange\(\)方法实现转速的改变,在Column\(\)中有添加下代码: + +``` +Image() +... +this.DescribeText('速度:',this.speed) + +Slider({value: this.speed, min: 1, max: 10,step: 1,style:SliderStyle.OUTSET}) + .showTips(true) + .blockColor(Color.Blue) + .onChange((value: number,mode:SliderChangeMode) => { + this.speed = value + clearInterval(this.interval) + this.speedChange() +}) +... +``` + +使用同样的方法,我们可以实现风车大小的改变,在Column\(\)中添加如下代码: + +``` +... +this.DescribeText('缩放比例:', this.imageSize) + +Slider({value: this.imageSize, min: 0.5, max: 2.5, step: 0.1,style:SliderStyle.OUTSET}) + .showTips(true) + .blockColor(Color.Blue) + .onChange((value: number, mode:SliderChangeMode) => { + this.imageSize = value +}) +... +``` + +自此我们已经完成了所有的工作:使用Slider、Image、Text组件,实现了一个可以调节风车大小和转速的简易应用。 + +# 恭喜你 + +在本篇Codelab中,我们主要为大家讲解了部分基础组件的使用,让大家可以通过简单的代码,上手eTS的开发,我们主要介绍了: + +- Slider组件的使用 +- Image组件的使用 +- @Builder注解的使用 + +同时逐步分解代码,和大家一起完成了的应用开发。希望通过本教程,各位开发者可以对基础组件有一个初步的了解,并对声明式编程框架具有新的认识。 + +# 参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/SliderApplicationEts) diff --git a/ETSUI/SliderApplicationEts/build.gradle b/ETSUI/SliderApplicationEts/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..8091e0ece10575993ba570722aadd6788144f460 --- /dev/null +++ b/ETSUI/SliderApplicationEts/build.gradle @@ -0,0 +1,34 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + supportSystem "standard" +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } + dependencies { + classpath 'com.huawei.ohos:hap:3.0.3.4' + classpath 'com.huawei.ohos:decctest:1.2.6.0' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } +} diff --git a/ETSUI/SliderApplicationEts/entry/.gitignore b/ETSUI/SliderApplicationEts/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7d5b7a94f4dcf381f03ff21f28f8a2494b58023f --- /dev/null +++ b/ETSUI/SliderApplicationEts/entry/.gitignore @@ -0,0 +1,2 @@ +/build +/node_modules diff --git a/ETSUI/SliderApplicationEts/entry/build.gradle b/ETSUI/SliderApplicationEts/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..1587dd1948941f3eaaf092ae6cae7969cb6895ff --- /dev/null +++ b/ETSUI/SliderApplicationEts/entry/build.gradle @@ -0,0 +1,21 @@ +apply plugin: 'com.huawei.ohos.hap' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + defaultConfig { + compatibleSdkVersion 7 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13.1' +} diff --git a/ETSUI/SliderApplicationEts/entry/proguard-rules.pro b/ETSUI/SliderApplicationEts/entry/proguard-rules.pro new file mode 100644 index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a --- /dev/null +++ b/ETSUI/SliderApplicationEts/entry/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/ETSUI/SliderApplicationEts/entry/src/main/config.json b/ETSUI/SliderApplicationEts/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..917ba8c8f9bc0c19a3eba884df674e182d27e2d6 --- /dev/null +++ b/ETSUI/SliderApplicationEts/entry/src/main/config.json @@ -0,0 +1,66 @@ +{ + "app": { + "bundleName": "com.example.sliderapplicationetsopenh", + "vendor": "example", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "com.example.sliderapplicationetsopenh", + "name": ".MyApplication", + "mainAbility": ".MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "visible": true, + "srcPath": "MainAbility", + "name": ".MainAbility", + "srcLanguage": "ets", + "icon": "$media:icon", + "description": "$string:description_mainability", + "formsEnabled": false, + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "mode": { + "syntax": "ets", + "type": "pageAbility" + }, + "pages": [ + "pages/index" + ], + "name": ".MainAbility", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} \ No newline at end of file diff --git a/ETSUI/SliderApplicationEts/entry/src/main/ets/MainAbility/app.ets b/ETSUI/SliderApplicationEts/entry/src/main/ets/MainAbility/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..b7a0995c8e441cac86e21e06e7c9071664482b1c --- /dev/null +++ b/ETSUI/SliderApplicationEts/entry/src/main/ets/MainAbility/app.ets @@ -0,0 +1,8 @@ +export default { + onCreate() { + console.info('Application onCreate') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} \ No newline at end of file diff --git a/ETSUI/SliderApplicationEts/entry/src/main/ets/MainAbility/pages/index.ets b/ETSUI/SliderApplicationEts/entry/src/main/ets/MainAbility/pages/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cba6476e375c68a4959d95253f2de1568e2081cd --- /dev/null +++ b/ETSUI/SliderApplicationEts/entry/src/main/ets/MainAbility/pages/index.ets @@ -0,0 +1,80 @@ +@Entry +@Component +struct Index { + @State private speed: number = 5 + @State private imageSize: number = 1 + @State private angle: number = 0 + @State private interval: number = 0 + + @Builder DescribeText(text:string, speed: number) { + Stack() { + Text(text + speed.toFixed(1)) + .margin({ top: 30 }) + .fontSize(20) + .fontWeight(FontWeight.Bold) + } + } + + build() { + Column() { + Row(){ + Image($r('app.media.windmill')) + .objectFit(ImageFit.Contain) + .height(150) + .width(150) + .position({ x: 110, y: 100 }) + .rotate({ x: 0, y: 0, z: 1, angle: this.angle }) + .scale({ x: this.imageSize, y: this.imageSize }) + } + .width(375) + .height(375) + + this.DescribeText('速度:', this.speed) + + Slider({ + value: this.speed, + min: 1, + max: 10, + step: 1, + style: SliderStyle.OUTSET + }) + .showTips(true) + .blockColor(Color.Blue) + .onChange((value: number, mode: SliderChangeMode) => { + this.speed = value + console.log("value:" + value); + clearInterval(this.interval) + this.speedChange() + }) + + this.DescribeText('缩放比例:', this.imageSize) + + Slider({ + value: this.imageSize, + min: 0.5, + max: 2.5, + step: 0.1, + style: SliderStyle.OUTSET + }) + .showTips(true) + .blockColor(Color.Blue) + .onChange((value: number, mode: SliderChangeMode) => { + this.imageSize = value + }) + } + .margin({ left: 30, right: 30 }) + } + + speedChange() { + var that = this; + that.angle = 0; + this.interval = setInterval(function () { + that.angle += that.speed + }, 15) + } + + onPageShow() { + clearInterval(this.interval) + this.speedChange() + } +} diff --git a/ETSUI/SliderApplicationEts/entry/src/main/resources/base/element/string.json b/ETSUI/SliderApplicationEts/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..03b8532c53ca563f8ed6b1e21d20ad3f67a68906 --- /dev/null +++ b/ETSUI/SliderApplicationEts/entry/src/main/resources/base/element/string.json @@ -0,0 +1,12 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "entry_MainAbility" + }, + { + "name": "description_mainability", + "value": "ETS_Empty Ability" + } + ] +} \ No newline at end of file diff --git a/ETSUI/SliderApplicationEts/entry/src/main/resources/base/media/icon.png b/ETSUI/SliderApplicationEts/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ETSUI/SliderApplicationEts/entry/src/main/resources/base/media/icon.png differ diff --git a/ETSUI/SliderApplicationEts/entry/src/main/resources/base/media/windmill.png b/ETSUI/SliderApplicationEts/entry/src/main/resources/base/media/windmill.png new file mode 100644 index 0000000000000000000000000000000000000000..9e6e0cfffaffaa4d2396c2752bf615fe7e55d461 Binary files /dev/null and b/ETSUI/SliderApplicationEts/entry/src/main/resources/base/media/windmill.png differ diff --git a/ETSUI/SliderApplicationEts/figures/zh-cn_image_0000001189625832.gif b/ETSUI/SliderApplicationEts/figures/zh-cn_image_0000001189625832.gif new file mode 100644 index 0000000000000000000000000000000000000000..c486513ccf3baa7831e4a3e7093ff95aa03c78a5 Binary files /dev/null and b/ETSUI/SliderApplicationEts/figures/zh-cn_image_0000001189625832.gif differ diff --git a/ETSUI/SliderApplicationEts/figures/zh-cn_image_0000001190942198.png b/ETSUI/SliderApplicationEts/figures/zh-cn_image_0000001190942198.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d6953d4a159507c67d9e25926e51dcc93ff9d1 Binary files /dev/null and b/ETSUI/SliderApplicationEts/figures/zh-cn_image_0000001190942198.png differ diff --git a/ETSUI/SliderApplicationEts/figures/zh-cn_image_0000001190968020.png b/ETSUI/SliderApplicationEts/figures/zh-cn_image_0000001190968020.png new file mode 100644 index 0000000000000000000000000000000000000000..8069d75078f80bf11a6d7a802eba216707f8ab5b Binary files /dev/null and b/ETSUI/SliderApplicationEts/figures/zh-cn_image_0000001190968020.png differ diff --git a/ETSUI/SliderApplicationEts/figures/zh-cn_other_0000001190624180.jpeg b/ETSUI/SliderApplicationEts/figures/zh-cn_other_0000001190624180.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..6b853f5c8082495e583df7b99bd4e42cb89b9c02 Binary files /dev/null and b/ETSUI/SliderApplicationEts/figures/zh-cn_other_0000001190624180.jpeg differ diff --git "a/ETSUI/SliderApplicationEts/figures/\345\217\226\347\211\210\346\234\254.png" "b/ETSUI/SliderApplicationEts/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/ETSUI/SliderApplicationEts/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/ETSUI/SliderApplicationEts/figures/\346\210\252\345\233\276.png" "b/ETSUI/SliderApplicationEts/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/ETSUI/SliderApplicationEts/figures/\346\210\252\345\233\276.png" differ diff --git a/ETSUI/SliderApplicationEts/gradle/wrapper/gradle-wrapper.jar b/ETSUI/SliderApplicationEts/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9 Binary files /dev/null and b/ETSUI/SliderApplicationEts/gradle/wrapper/gradle-wrapper.jar differ diff --git a/ETSUI/SliderApplicationEts/gradle/wrapper/gradle-wrapper.properties b/ETSUI/SliderApplicationEts/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..f59159e865d4b59feb1b8c44b001f62fc5d58df4 --- /dev/null +++ b/ETSUI/SliderApplicationEts/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/ETSUI/SliderApplicationEts/public_sys-resources/icon-caution.gif b/ETSUI/SliderApplicationEts/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/SliderApplicationEts/public_sys-resources/icon-caution.gif differ diff --git a/ETSUI/SliderApplicationEts/public_sys-resources/icon-danger.gif b/ETSUI/SliderApplicationEts/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/SliderApplicationEts/public_sys-resources/icon-danger.gif differ diff --git a/ETSUI/SliderApplicationEts/public_sys-resources/icon-note.gif b/ETSUI/SliderApplicationEts/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/ETSUI/SliderApplicationEts/public_sys-resources/icon-note.gif differ diff --git a/ETSUI/SliderApplicationEts/public_sys-resources/icon-notice.gif b/ETSUI/SliderApplicationEts/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/ETSUI/SliderApplicationEts/public_sys-resources/icon-notice.gif differ diff --git a/ETSUI/SliderApplicationEts/public_sys-resources/icon-tip.gif b/ETSUI/SliderApplicationEts/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/ETSUI/SliderApplicationEts/public_sys-resources/icon-tip.gif differ diff --git a/ETSUI/SliderApplicationEts/public_sys-resources/icon-warning.gif b/ETSUI/SliderApplicationEts/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/SliderApplicationEts/public_sys-resources/icon-warning.gif differ diff --git a/ETSUI/SliderApplicationEts/settings.gradle b/ETSUI/SliderApplicationEts/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07 --- /dev/null +++ b/ETSUI/SliderApplicationEts/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/ETSUI/SliderApplictionEts/README.md b/ETSUI/SliderApplictionEts/README.md deleted file mode 100644 index 1586e959ede664d5e6d51c66ca6e914593515558..0000000000000000000000000000000000000000 --- a/ETSUI/SliderApplictionEts/README.md +++ /dev/null @@ -1,2 +0,0 @@ -tmp - diff --git a/ETSUI/TransitionAnimtaionEts/LICENSE b/ETSUI/TransitionAnimtaionEts/LICENSE index 7c357dc828cf7d8c783f10ed6bb1bac8a1e903c1..80576ef141485b36eea4aebf25af97020bc2de44 100644 --- a/ETSUI/TransitionAnimtaionEts/LICENSE +++ b/ETSUI/TransitionAnimtaionEts/LICENSE @@ -1,10 +1,10 @@ - Copyright (c) 2021 Huawei Device Co., Ltd. + Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. - Licensed under the Apache License,Version 2.0 (the "License"); + 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 + 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, diff --git a/ETSUI/TransitionAnimtaionEts/README.md b/ETSUI/TransitionAnimtaionEts/README.md index 2eec5e577106cbc5bf2e28580d785fd67f746024..93bd54d861cd39c0e6ee90d23fb866a3598ad7a5 100644 --- a/ETSUI/TransitionAnimtaionEts/README.md +++ b/ETSUI/TransitionAnimtaionEts/README.md @@ -1,2 +1,381 @@ -TransitionAnimtaionETS -基于OpenHarmony eTS转场动画,实现了页面间转场、组件内转场以及共享元素转场。 \ No newline at end of file +# SliderApplicationEts +# 介绍 + +- [应用场景](#section225718574575) + +## 应用场景 + +OpenHarmony eTS提供了丰富的动画组件和接口,开发者可以根据实际场景和开发需求,选用不同的组件和接口来实现不同的动画效果。 + +在本教程中,我们将会通过一个简单的样例,学习如何使用eTS开发框架的转场动画。其中包含页面间转场、组件内转场以及共享元素转场,完成效果如下图所示: + +![](figures/VID_20211221_194349-00_00_00-00_00_30-2.gif) + +# 相关概念 + +- [eTS工程目录](#section116501561575) + +**页面间转场**:在两个页面之间切换时执行过渡动效。 + +**组件内转场**:在组件添加和移除时执行过渡动效,主要用于容器组件子组件添加和移除时提升用户体验。 + +**共享元素转场**:元素在不同页面之间过渡动效。例如,如果两个页面使用相同的图片(但位置和大小不同),图片就会在这两个页面之间流畅地平移和缩放。 + +## eTS工程目录 + +新建工程的eTS目录如下图所示。 + +![](figures/zh-cn_image_0000001236728127.png) + +**各个文件夹和文件的作用:** + +- **index.ets**:用于描述UI布局、样式、事件交互和页面逻辑。 +- **app.ets**:用于全局应用逻辑和应用生命周期管理。 +- **pages**:用于存放所有组件页面。 +- **resources**:用于存放资源配置文件。 + +# 任务一:构建主界面 + +在这个任务中,我们将完成示例主界面的设计,效果图如下: + +![](figures/zh-cn_other_0000001191964634.jpeg) + +从上面效果图可以看出,主界面主要由5个相同样式的功能菜单组成,我们可以将这些菜单抽取成一个子组件Item。 + +1. 将所需要的图片添加到resources -\> base -\> media 目录下。 + + ![](figures/zh-cn_image_0000001237187351.png) + +2. 在index.ets中新建名为Item的子组件,声明子组件Item的UI布局并添加样式。创建Stack组件,包含图片和文本,并在已创建的Item组件中添加文本信息和页面跳转事件,定义变量text和uri。其中text用于给Text组件设置文本信息,uri用于设置页面路由的地址。示例代码如下: + + ``` + @Component + struct Item { + // 文本信息 + private text: string + + // 页面跳转uri + private uri: string + + build() { + Stack({ alignContent: Alignment.Center }) { + Image($r('app.media.image3')) + .objectFit(ImageFit.Cover) + .width('100%') + .height(100) + .borderRadius(15) + + Text(this.text) + .fontSize(20) + .fontWeight(FontWeight.Bold) + .fontColor(Color.Black) + } + .onClick(() => { + router.push({ uri: this.uri }) + }) + .height(120) + .borderRadius(15) + .width('80%') + .margin({ bottom: 20 }) + } + } + ``` + +3. 将Item组件添加到Index组件中,并给Item传入参数text和uri,由于还未创建要跳转的页面,所以这里uri暂时传空字符串。 + + ``` + @Entry + @Component + struct Index { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Item({ text: '页面间转场:底部滑入', uri: '' }) + Item({ text: '页面间转场:自定义1', uri: '' }) + Item({ text: '页面间转场:自定义2', uri: '' }) + Item({ text: '组件内转场', uri: '' }) + Item({ text: '共享元素转场', uri: '' }) + } + .width('100%') + .height('100%') + .backgroundColor('#FFECECEC') + } + } + + @Component + struct Item { + ...... + } + ``` + +# 任务二:实现页面间转场 + +- 新建页面 + +1. 首先在pages目录下新建名为page的package,然后在page目录下,点击鼠标右键分别新建名为BottomTransition、CustomTransition和FullCustomTransition的三个ets文件。其中BottomTransition用于实现“页面间转场:底部滑入”动效;CustomTransition用于实现“页面间转场:自定义1”动效;FullCustomTransition用于实现“页面间转场:自定义2”动效 + + ![](figures/zh-cn_image_0000001192120584.png) + + >![](public_sys-resources/icon-note.gif) **说明:** + > + >- 页面文件名不能使用组件名称,比如:Text.ets、Button.ets等。 + >- 每个页面文件中必须包含入口组件。 + +2. 在config.json文件的pages标签下分别添加BottomTransition、CustomTransition和FullCustomTransition的路由地址。 + + ``` + "pages": [ + "pages/Index", + "pages/page/BottomTransition", + "pages/page/CustomTransition", + "pages/page/FullCustomTransition" + ] + ``` + + >![](public_sys-resources/icon-note.gif) **说明:** + >pages列表中第一个页面为应用的首页入口。 + +3. 在主界面index.ets的Index组件中,将BottomTransition、CustomTransition和FullCustomTransition的路由地址赋值给对应Item的uri。 + + ``` + @Entry + @Component + struct Index { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Item({ text: '页面间转场:底部滑入', uri: 'pages/page/BottomTransition' }) + Item({ text: '页面间转场:自定义1', uri: 'pages/page/CustomTransition' }) + Item({ text: '页面间转场:自定义2', uri: 'pages/page/FullCustomTransition' }) + Item({ text: '组件内转场', uri: '' }) + Item({ text: '共享元素转场', uri: '' }) + } + .width('100%') + .height('100%') + .backgroundColor('#FFECECEC') + } + } + ``` + + +- 实现“底部滑入”动效 + +在BottomTransition声明pageTransition方法配置转场参数,其中PageTransitionEnter用于自定义当前页面的入场效果,PageTransitionExit用于自定义当前页面的退场效果。 + +在这里我们设置PageTransitionEnter和PageTransitionExit的slide属性为SlideEffect.Bottom,来实现BottomTransition入场时从底部滑入,退场时从底部滑出。 + +``` +@Entry +@Component +struct BottomTransition{ + build() { + Stack() { + Image($r('app.media.image1')) + .objectFit(ImageFit.Cover) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + +// 页面转场通过全局transition方法配置转场参数 + pageTransition() { + + // 页面入场组件:SlideEffect.Bottom 设置到入场时表示从下边滑入,出场时表示滑出到下边。 + PageTransitionEnter({ duration: 600, curve: Curve.Smooth }) + .slide(SlideEffect.Bottom) + + // 页面退场组件:SlideEffect.Bottom 设置到入场时表示从下边滑入,出场时表示滑出到下边。 + PageTransitionExit({ duration: 600, curve: Curve.Smooth }) + .slide(SlideEffect.Bottom) + } +} +``` + +# 任务三:实现组件内转场 + +本节实现组件内转场动效,通过一个按钮来控制组件的添加和移除,呈现容器组件子组件添加和移除时的动效。 + +组件转场主要通过transition属性方法配置转场参数,在组件添加和移除时会执行过渡动效,需要配合animateTo才能生效。动效时长、曲线、延时跟随animateTo中的配置。 + +1. 在pages目录下,新建名为ComponentTransition的ets文件,然后在config.json文件下的pages标签下添加ComponentTransition的路由地址。 + + ``` + "pages": [ + "pages/Index", + "pages/page/BottomTransition", + "pages/page/CustomTransition", + "pages/page/FullCustomTransition", + "pages/ComponentTransition" + ] + ``` + +2. 在ComponentTransition.ets文件中,新建ComponentItem子组件,添加Stack组件和Image组件。给Stack添加两个transition属性,分别用于定义组件的添加动效和移除动效。 + + ``` + @Component + struct ComponentItem { + build() { + Stack({ alignContent: Alignment.Center }) { + Image($r('app.media.image3')) + .objectFit(ImageFit.Cover) + .width('100%') + .height(120) + .borderRadius(15) + } + .height(120) + .borderRadius(15) + .width('80%') + .padding({ top: 20 }) + // 组件添加时x、y轴缩放从0.5变化到1,透明度从0到1 + .transition({ type: TransitionType.Insert, scale: { x: 0.5, y: 0.5 }, opacity: 0 }) + // 组件移除时沿y轴旋转360度 + .transition({ type: TransitionType.Delete, rotate: { x: 0, y: 1, z: 0, angle: 360 }, scale: { x: 0, y: 0 } }) + } + } + + @Entry + @Component + struct ComponentTransition { + ... + } + ``` + +3. 在ComponentTransition组件定义一个变量,用于控制ComponentItem的添加和移除,在Button组件的onClick事件中添加animateTo方法,来使ComponentItem子组件动效生效。 + + ``` + @Component + struct ComponentItem { + ... + } + + + @Entry + @Component + struct ComponentTransition { + @State private isShow: boolean= false + + build() { + Column() { + if (this.isShow) { + ComponentItem() + } + + ComponentItem() + + Button("Toggle") + .onClick(() => { + //执行动效,动效时长600ms + animateTo({ duration: 600 }, () => { + this.isShow = !this.isShow; + }) + }) + .height(45) + .width(200) + .fontColor(Color.Black) + .backgroundColor('rgb(181,222,224)') + .margin({ top: 20 }) + } + .padding({ left: 20, right: 20 }) + .backgroundColor('#FFECECEC') + .height('100%') + .width('100%') + } + } + ``` + +# 任务四:实现元素共享转场 + +共享元素转场通过给组件设置sharedTransition属性来实现,两个页面的组件配置为同一个id,则转场过程中会执行共享元素转场。sharedTransition可以设置动效的时长、动画曲线和延时,实现步骤如下: + +1. 首先在pages目录下新建名为share的包,然后在share目录下分别新建名为ShareItem和SharePage的ets文件。其中ShareItem.ets用于展示小图,SharePage.ets用于展示大图。 + + ![](figures/zh-cn_image_0000001192441454.png) + +2. 在config.json文件下的pages标签下分别添加ShareItem和SharePage的路由地址。 + + ``` + "pages": [ "pages/Index", "pages/page/BottomTransition", "pages/page/CustomTransition", "pages/page/FullCustomTransition", "pages/ComponentTransition", "pages/share/ShareItem", "pages/share/SharePage"] + ``` + +3. 在ShareItem.ets中给Image组件设置sharedTransition属性,组件转场id设置为“imageId”。 + + ``` + import router from '@system.router' + + @Entry + @Component + struct ShareItem{ + build() { + Flex() { + Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { + Stack() { + Image($r('app.media.image2')) + // 设置共享元素转场属性 + .sharedTransition('imageId', { duration: 600, curve: Curve.Smooth, delay: 100 }) + .onClick(() => { + router.push({ uri: 'pages/share/SharePage' }) + }) + .objectFit(ImageFit.Cover) + .height('100%') + .width('100%') + .borderRadius(15) + } + .height('100%') + .width('100%') + + Text('点击查看共享元素转场动效') + .fontSize(20) + .fontColor(Color.Black) + .fontWeight(FontWeight.Regular) + .margin({ left: 10, right: 10 }) + + } + .height(120) + .backgroundColor('rgb(181,222,224)') + .borderRadius(15) + .margin({ top: 20 }) + } + .width('100%') + .padding({ left: 16, right: 16 }) + .backgroundColor('#FFECECEC') + } + } + ``` + + >![](public_sys-resources/icon-note.gif) **说明:** + >两个页面的组件配置为同一个id,则转场过程中会执行共享元素转场,配置为空字符串时不会有共享元素转场效果。 + +4. 在SharePage.ets中给Image组件设置sharedTransition属性,组件转场id设置为“imageId”。 + + ``` + @Entry + @Component + struct SharePage{ + build() { + Stack() { + Image($r('app.media.image2')) + // 设置共享元素转场属性 + .sharedTransition('imageId', { duration: 1000, curve: Curve.Smooth, delay: 100 }) + .objectFit(ImageFit.Cover) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } + ``` + +# 恭喜你 + +在本篇Codelab中,我们主要用到了以下知识点: + +- 转场动画 +- 路由 + +本示例代码从布局、样式、响应事件三个层面,逐步实现了页面间转场、组件内转场以及共享元素转场。希望通过本教程,各位开发者可以对转场动画具有更深刻的认识。 + +# 参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/TransitionAnimtaionEts) + diff --git a/ETSUI/TransitionAnimtaionEts/figures/VID_20211221_194349-00_00_00-00_00_30-2.gif b/ETSUI/TransitionAnimtaionEts/figures/VID_20211221_194349-00_00_00-00_00_30-2.gif new file mode 100644 index 0000000000000000000000000000000000000000..1b034952e46d3db1553f62d31c269838cdcaf7d5 Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/figures/VID_20211221_194349-00_00_00-00_00_30-2.gif differ diff --git a/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001192120584.png b/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001192120584.png new file mode 100644 index 0000000000000000000000000000000000000000..c2c2de94e460d6ffbd14be60cced2f02de70caa6 Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001192120584.png differ diff --git a/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001192441454.png b/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001192441454.png new file mode 100644 index 0000000000000000000000000000000000000000..0708de4dda2b1eb425bb2306b26c1e992712ee1a Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001192441454.png differ diff --git a/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001236728127.png b/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001236728127.png new file mode 100644 index 0000000000000000000000000000000000000000..8069d75078f80bf11a6d7a802eba216707f8ab5b Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001236728127.png differ diff --git a/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001237187351.png b/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001237187351.png new file mode 100644 index 0000000000000000000000000000000000000000..1aa6861706ea58ee66ea95869794c1a8902ce72b Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/figures/zh-cn_image_0000001237187351.png differ diff --git a/ETSUI/TransitionAnimtaionEts/figures/zh-cn_other_0000001191964634.jpeg b/ETSUI/TransitionAnimtaionEts/figures/zh-cn_other_0000001191964634.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..a4729a0465d2cc8872cd162df0051ad2ebbf3697 Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/figures/zh-cn_other_0000001191964634.jpeg differ diff --git "a/ETSUI/TransitionAnimtaionEts/figures/\345\217\226\347\211\210\346\234\254.png" "b/ETSUI/TransitionAnimtaionEts/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/ETSUI/TransitionAnimtaionEts/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/ETSUI/TransitionAnimtaionEts/figures/\346\210\252\345\233\276.png" "b/ETSUI/TransitionAnimtaionEts/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/ETSUI/TransitionAnimtaionEts/figures/\346\210\252\345\233\276.png" differ diff --git a/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-caution.gif b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-caution.gif differ diff --git a/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-danger.gif b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-danger.gif differ diff --git a/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-note.gif b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-note.gif differ diff --git a/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-notice.gif b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-notice.gif differ diff --git a/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-tip.gif b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-tip.gif differ diff --git a/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-warning.gif b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/ETSUI/TransitionAnimtaionEts/public_sys-resources/icon-warning.gif differ diff --git a/JSUI/AnimationDemo/README.md b/JSUI/AnimationDemo/README.md index 60609f9fb1020a976057c2abe0d93b537694d329..2734120993b396081d82c5a69da23253b9f20966 100644 --- a/JSUI/AnimationDemo/README.md +++ b/JSUI/AnimationDemo/README.md @@ -1,4 +1,193 @@ -# AnimationDemo -简介 -• 此demo使用的是通用动画样式,我们通过一个简单的样例,实现了平移、旋转、缩放以及透明度变化的效果。 +# 1.介绍 +本篇Codelab,我们将一起学习ArkUI(基于JS扩展的类Web开发范式)通用动画样式的使用。 + +在本教程中,我们通过一个简单的样例,实现了平移、旋转、缩放以及透明度变化的效果,效果图如下: + +![](figures/VID_20211228_142129-00_00_00-00_00_30.gif) + +# 2.相关概念 + +**[image组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-image.md):**图片组件,用于图片资源的展示。 + +# 3.搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 4.将组件添加到布局文件中 + +在这个任务中,我们需要完成程序页面的新建和设计,并将程序使用到的input组件添加到布局文件index.hml中。在完成新建项目后,我们看到系统自动创建了pages.index目录,在这个目录下,我们找到index.hml文件,开始进行页面设计。 + +打开index.hml文件,默认代码使用div组件和text组件来共同呈现文本显示的效果,具体代码如下: + +``` +
+ + {{ $t('strings.hello') }} {{ title }} + +
+``` + +开发者可以删除默认代码,并跟着接下来的步骤一起开发,实现如下界面效果。 + +从上面布局效果图可以看到,界面主要由image组件和text组件组成,我们现在index.html中添加image组件和text组件,并添加对应的class,用于设置组件的显示效果,代码如下: + +``` +
+ + translate + + rotate + + rotateY + + scale + + opacity +
+``` + +# 5.为页面设计样式 + +在这个任务中,我们将一起为任务二中写好的页面添加样式,上面所有的组件都定义了class属性,它对应的样式都定义在index.css中,有关css更多的知识可以参考[CSS语法参考](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-framework-syntax-css.md)。 + +这部分定义了整个页面中各个组件的样式。在index.css中先添加如下代码: + +``` +.container { + background-color: #F8FCF5; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.img { + margin-top: 10px; + height: 100px; + width: 100px; + animation-timing-function: ease; + animation-duration: 2s; + animation-delay: 0s; + animation-fill-mode: forwards; + animation-iteration-count: infinite; +} + +.text { + font-size: 20px; +} + +.img-translate { + animation-name: translateAnim; +} + +.img-rotate { + animation-name: rotateAnim; +} + +.img-rotateY { + animation-name: rotateYAnim; +} + +.img-scale { + animation-name: scaleAnim; +} + +.img-mixes { + animation-name: mixesAnim; +} + +.img-opacity { + animation-name: opacityAnim; +} + +/*从-100px平移到100px*/ +@keyframes translateAnim { + from { + transform: translate(-100px); + } + + to { + transform: translate(100px); + } +} + +/*从0°旋转到360°*/ +@keyframes rotateAnim { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} + +/*沿Y轴旋转,从0°旋转到360°*/ +@keyframes rotateYAnim { + from { + transform: rotateY(0deg); + } + + to { + transform: rotateY(360deg); + } +} + +/*从0倍缩放到1.2倍大小*/ +@keyframes scaleAnim { + from { + transform: scale(0); + } + + to { + transform: scale(1.2); + } +} + +/*透明度从0变化到1*/ +@keyframes opacityAnim { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} +``` + +更多动画样式可以参考[动画样式](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-common-animation.md)章节。 + +# 6.恭喜你 + +在本篇Codelab中,我们主要为大家讲解了ArkUI(基于JS扩展的类Web开发范式)通用动画样式的使用。 + +通过一个代码示例,实现image组件的平移、缩放、旋转和透明度变化动效。希望通过本教程,各位开发者可以对JS通用动画样式具有更深刻的认识。 + +# 7.参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/JSUI/AnimationDemo) \ No newline at end of file diff --git a/JSUI/AnimationDemo/entry/build.gradle b/JSUI/AnimationDemo/entry/build.gradle index 68ec4e15705e1c4fd6ca07fe7ad0444a86546c7a..1587dd1948941f3eaaf092ae6cae7969cb6895ff 100644 --- a/JSUI/AnimationDemo/entry/build.gradle +++ b/JSUI/AnimationDemo/entry/build.gradle @@ -13,11 +13,9 @@ ohos { } } } - - } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) - testImplementation 'junit:junit:4.13' + testImplementation 'junit:junit:4.13.1' } diff --git a/JSUI/AnimationDemo/figures/VID_20211228_142129-00_00_00-00_00_30.gif b/JSUI/AnimationDemo/figures/VID_20211228_142129-00_00_00-00_00_30.gif new file mode 100644 index 0000000000000000000000000000000000000000..ada2bfafe70d13c98c83b2588d75a4bd5d2f88c5 Binary files /dev/null and b/JSUI/AnimationDemo/figures/VID_20211228_142129-00_00_00-00_00_30.gif differ diff --git "a/JSUI/AnimationDemo/figures/\345\217\226\347\211\210\346\234\254.png" "b/JSUI/AnimationDemo/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/JSUI/AnimationDemo/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/JSUI/AnimationDemo/figures/\346\210\252\345\233\276.png" "b/JSUI/AnimationDemo/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/JSUI/AnimationDemo/figures/\346\210\252\345\233\276.png" differ diff --git a/JSUI/AnimationDemo/public_sys-resources/icon-caution.gif b/JSUI/AnimationDemo/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/AnimationDemo/public_sys-resources/icon-caution.gif differ diff --git a/JSUI/AnimationDemo/public_sys-resources/icon-danger.gif b/JSUI/AnimationDemo/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/AnimationDemo/public_sys-resources/icon-danger.gif differ diff --git a/JSUI/AnimationDemo/public_sys-resources/icon-note.gif b/JSUI/AnimationDemo/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/JSUI/AnimationDemo/public_sys-resources/icon-note.gif differ diff --git a/JSUI/AnimationDemo/public_sys-resources/icon-notice.gif b/JSUI/AnimationDemo/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/JSUI/AnimationDemo/public_sys-resources/icon-notice.gif differ diff --git a/JSUI/AnimationDemo/public_sys-resources/icon-tip.gif b/JSUI/AnimationDemo/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/JSUI/AnimationDemo/public_sys-resources/icon-tip.gif differ diff --git a/JSUI/AnimationDemo/public_sys-resources/icon-warning.gif b/JSUI/AnimationDemo/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/AnimationDemo/public_sys-resources/icon-warning.gif differ diff --git a/JSUI/ClickableJsDemo/README.md b/JSUI/ClickableJsDemo/README.md index 84a651f04fd7a8d6fddb92320142e8e1918beeba..0469906dc7e3eed6ffa071e75048748d3bca5747 100644 --- a/JSUI/ClickableJsDemo/README.md +++ b/JSUI/ClickableJsDemo/README.md @@ -1,4 +1,501 @@ #ClickableJsDemo -简介 • OpenHarmony JSUI提供了常用的布局、组件等页面元素,并且为这些组件提供了很多属性与可监听到的事件(例如动画属性与点击、触碰事件),开发者可以根据实际场景和开发需求,选用不同的组件、事件、属性来实现界面交互效果的设计,本篇CodeLab,我们将一起开启JS UI基础组件与动画的学习之路。本教程主要涉及到的页面元素有有image,image-animator。 - 在本文中,CodeLab将会通过几个简单的样例,展现图片资源在界面交互中几种常见运用效果。它旨在帮助开发人员快速了解openHarmony JSUI应用的开发。 \ No newline at end of file +# 介绍 + +- [应用场景](#section225718574575) + +OpenHarmony ArkUI(基于JS扩展的类Web开发范式)提供了常用的图片、图片帧动画播放器组件,并且为这些组件提供了很多属性与可监听到的事件(例如动画属性与点击、触碰事件)。开发者可以根据实际场景和开发需求,选用不同的组件、事件、属性来实现界面交互效果的设计,本篇CodeLab,我们将一起开启ArkUI(基于JS扩展的类Web开发范式)基础组件与动画的学习之路。本教程主要涉及到的页面元素有image,image-animator。 + +![](figures/IMG_20211208_192923.jpg) + +## 应用场景 + +- 社交、办公类等应用中涉及到交互、导航、拨打电话或者语音的场景。 + +# 相关概念 + +**[image组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-image.md)**:图片组件,用于图片资源的展示。 + +**[image-animitor组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-image-animator.md)**:帧动画播放器,用以播放一组图片,可以设置播放时间、次数等参数。 + +**[通用事件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-common-events.md)**:事件绑定在组件上,当组件达到事件触发条件时,会执行JS中对应的事件回调函数,实现页面UI视图和页面JS逻辑层的交互。 + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 任务一:完成页面布局 + +在这个任务中,我们需要完成UI界面的设置。具体步骤: + +- 准备好所使用的图片等相关资源。 +- 准备好样式文件index.css。 +- 编写好图形背景数据。 +- 编写主页面。 + +1. 在default/common/images目录下放入案例要用到的图片,在default/common/下创建css文件夹并放入公共样式文件style.css。 + + 图片与样式文件放置位置 + + ![](figures/截图1.png) + +2. 在default/pages/index/index.css中引入公共样式style.css并编写需要用到的样式,样式代码如下: + + ``` + @import '../../common/css/style.css'; + .container { + flex-direction: column; + align-items: center; + } + .container-son-div{ + width: 100%; + height: 200px; + } + .line-div{ + flex-direction: column; + width: 50%; + height: 180px; + } + .line-div-son{ + flex-direction: column; + width: 100%; + align-items: center; + justify-content: center; + } + .text-div{ + position: absolute; + bottom: 0; + left: 50%; + transform: translate(-50%, -50%); + } + + .img-normal{ + width:80px; + height:80px + } + .main-img-unTouch{ + width: 100px; + height: 100px; + border:0px solid #777676; + } + .main-img-touch{ + width: 110px; + height: 110px; + border:4px solid #777676; + } + .animator { + width: 100px; + height: 100px; + } + ``` + +3. 在src/main/js/default/pages/index/index.js中准备好所需要用到的数据。 + + imageNormal + + ``` + imageNormal: { + classType: "main-img-unTouch", + src: "/common/images/sky_blue.png", + title: "点击阴影" + } + ``` + + imageNormal为image(第一张图)所需要的数据,参数说明如下: + + - classType:css样式 + - src:图片路径 + - title:辅助说明的文字内容 + + imageSelect + + imageSelect为image(第二张图)所需要的数据,参数说明如下: + + - src:图片路径 + - title:辅助说明的文字内容 + - hook:当前是否为打钩状态 + + ``` + imageSelect: { + src: "/common/images/hook.png", + title: "点击切换状态", + hook: true + } + ``` + + frameContainerPhone + + frameContainerPhone为image-animator(帧动画电话来电效果)所需要的数据,参数说明如下: + + - frames:帧动画所使用的的图片路径数组 + - title:辅助说明的文字内容 + + ``` + frameContainerPhone: { + frames: [ + {src: "/common/images/frames/phone/phone_0.png"}, + {src: "/common/images/frames/phone/phone_1.png"}, + {src: "/common/images/frames/phone/phone_2.png"}, + ... + {src: "/common/images/frames/phone/phone_57.png"} + ], + title: "点击动画效果" + } + ``` + + frameContainerState + + frameContainerState为image-animator(帧动画状态切换效果)所需要的数据,参数说明如下: + + - frames:帧动画所使用的的图片路径数组 + - src:默认背景图片路径 + - title:辅助说明的文字内容 + - flag:记录点击状态,每点击一次,改变一次值 + + ``` + frameContainerState: { + frames:[], + src: "/common/images/frames/arrowheadCollapse/arrowhead_collapse_0.png", + title: "点击切换状态动效", + durationTime: 0, + flag: true + } + ``` + + 其他数据 + + - durationTimeArray:帧动画播放时间数组 + - back:“后退”图标效果帧动画所需图片路径数组 + - collapse:“收起”图标效果帧动画所需图片路径数组 + + ``` + durationTimeArray:[1400,1400], + back:[ + {src: "/common/images/frames/arrowheadBack/arrowhead_back_0.png"}, + {src: "/common/images/frames/arrowheadBack/arrowhead_back_1.png"}, + {src: "/common/images/frames/arrowheadBack/arrowhead_back_2.png"}, + ... + {src: "/common/images/frames/arrowheadBack/arrowhead_back_13.png"} + ], + collapse:[ + {src: "/common/images/frames/arrowheadCollapse/arrowhead_collapse_0.png"}, + {src: "/common/images/frames/arrowheadCollapse/arrowhead_collapse_1.png"}, + {src: "/common/images/frames/arrowheadCollapse/arrowhead_collapse_2.png"}, + ... + {src: "/common/images/frames/arrowheadCollapse/arrowhead_collapse_13.png"} + ] + ``` + +4. 我们需要完成程序页面的新建和设计,并将程序使用到的image、image-animator组件添加到布局文件index.hml中。 + + 代码使用div组件和text组件来共同呈现文本显示的效果,其中div属于[基础容器](https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-container-div-0000000000611484),用作页面结构的根节点或将内容进行分组;text是[文本组件](https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-basic-text-0000000000611633),用于呈现一段信息。有关这个两个组件更多的知识,可以参考本系列教程的其他Codelab。 + + image组件 + + ![](figures/第一张图.png) + + ``` +
+
+ +
+
+ {{imageNormal.title}} +
+
+ ``` + + ![](figures/第二张图.png) + + ``` +
+
+ +
+
+ {{imageSelect.title}} +
+
+ ``` + + image-animator组件 + + ![](figures/第三张.jpg) + + ``` +
+
+ +
+
{{frameContainerPhone.title}}
+
+ ``` + + ![](figures/第四张.jpg) + + ``` +
+
+ +
+
{{frameContainerState.title}}
+
+ ``` + + index.hml全文如下: + + ``` +
+
+
+
+ +
+
{{imageNormal.title}}
+
+
+
+ +
+
{{imageSelect.title}}
+
+
+
+
+
+ +
+
{{frameContainerPhone.title}}
+
+
+
+ +
+
{{frameContainerState.title}}
+
+
+
+ ``` + +# 任务二:添加交互事件 + +1. 为图片组件\(ref=“imageNormal”\)添加ontouchstart\(\)、ontouchend\(\)事件,实现触碰时,图片大小、边框、透明度改变;触碰结束恢复初始效果。 + + - ontouchstart:手指刚触摸屏幕时触发该事件。 + - ontouchend:手指触摸结束离开屏幕时触发该事件。 + + ``` + + ``` + + ``` + changeShadow(flag) { + if (flag) { + this.imageNormal.classType = "main-img-touch" + } else { + this.imageNormal.classType = "main-img-unTouch" + } + } + ``` + +2. 为图片组件\(ref="imageSelect"\)添加onclick事件,实现点击切换图片效果。 + + - onclick:点击动作触发该事件。 + + ``` + + ``` + + ``` + changeHookState() { + if (this.imageSelect.hook) { + this.imageSelect.src = "/common/images/fork.png" + this.imageSelect.hook = false + } else { + this.imageSelect.src = "/common/images/hook.png" + this.imageSelect.hook = true + } + } + ``` + +3. 为图片帧动画播放器(ref="frameContainerPhone")添加onclick事件,实现点击播放帧动画效果。 + + ``` + + ``` + + ``` + handleStartFrameContainerPhone(){ + this.frameContainerPhone.durationTime = 5800 + this.$refs.frameContainerPhone.start(); + } + ``` + +4. 为图片帧动画播放器\(ref="frameContainerState"\)添加onclick事件,实现点击播放帧动画效果并切换状态、记录状态效果。 + + ``` + + ``` + + ``` + handleStartFrameContainerState(){ + if (this.frameContainerState.flag) { + this.frameContainerState.frames = this.collapse + this.frameContainerState.durationTime = this.durationTimeArray[0] + this.$refs.frameContainerState.start() + this.frameContainerState.flag = false + this.$refs.frameContainerState.stop() + } else { + this.frameContainerState.frames = this.back + this.frameContainerState.durationTime = this.durationTimeArray[1] + this.$refs.frameContainerState.start() + this.frameContainerState.flag = true + this.$refs.frameContainerState.stop() + } + } + ``` + +5. index.js全文如下: + + ``` + export default { + data: { + imageNormal: { + classType: 'main-img-unTouch', + src: '/common/images/sky_blue.png', + title: '点击阴影' + }, + imageSelect: { + src: '/common/images/hook.png', + title: '点击切换状态', + hook: true + }, + frameContainerPhone: { + frames: [{ + src: '/common/images/frames/phone/phone_0.png' + }, { + src: '/common/images/frames/phone/phone_1.png' + }, { + src: '/common/images/frames/phone/phone_2.png' + }, ...{ + src: '/common/images/frames/phone/phone_35.png' + }], + title: '点击动画效果', + durationTime: 3600 + }, + frameContainerState: { + frames: [], + title: '点击切换状态动效', + durationTime: 0, + flag: true + }, + durationTimeArray: [1400, 1400], + back: [{ + src: '/common/images/frames/arrowheadBack/arrowhead_back_0.png' + }, { + src: '/common/images/frames/arrowheadBack/arrowhead_back_1.png' + }, ...{ + src: '/common/images/frames/arrowheadBack/arrowhead_back_13.png' + }], + collapse: [{ + src: '/common/images/frames/arrowheadCollapse/arrowhead_collapse_0.png' + }, { + src: '/common/images/frames/arrowheadCollapse/arrowhead_collapse_1.png' + }, ...{ + src: '/common/images/frames/arrowheadCollapse/arrowhead_collapse_13.png' + }] + }, + // 初始化 + onInit() { + this.frameContainerState.frames = this.back; + this.frameContainerState.durationTime = 0; + this.frameContainerPhone.durationTime = 0; + }, + // 触碰阴影方法 + changeHookState() { + if (this.imageSelect.hook) { + this.imageSelect.src = '/common/images/fork.png'; + this.imageSelect.hook = false; + } else { + this.imageSelect.src = '/common/images/hook.png'; + this.imageSelect.hook = true; + } + }, + // 点击切换状态 + changeShadow(flag) { + if (flag) { + this.imageNormal.classType = 'main-img-touch'; + } else { + this.imageNormal.classType = 'main-img-unTouch'; + } + }, + // 点击动画效果方法 + handleStartFrameContainerPhone() { + this.frameContainerPhone.durationTime = 3600; + this.$refs.frameContainerPhone.start(); + }, + // 点击切换状态动效方法 + handleStartFrameContainerState() { + if (this.frameContainerState.flag) { + this.frameContainerState.frames = this.collapse; + this.frameContainerState.durationTime = this.durationTimeArray[0]; + this.$refs.frameContainerState.start(); + this.frameContainerState.flag = false; + this.$refs.frameContainerState.stop(); + } else { + this.frameContainerState.frames = this.back; + this.frameContainerState.durationTime = this.durationTimeArray[1]; + this.$refs.frameContainerState.start(); + this.frameContainerState.flag = true; + this.$refs.frameContainerState.stop(); + } + } + }; + ``` + +# 恭喜你 + +1. image + - image的src属性可以指定图片资源位置。 + - image的class属性可以设置图片样式,包括大小、边框、透明度等。 + +2. image-animator + - image-animator的images属性用来指定图片路径数组。 + - image-animator的duration属性用来设置播放时间。 + + +通过本代码示,实现了触碰 image改变图片的大小、边框、透明度,点击切换图片;点击image-animator切换帧动画图片资源以及播放帧动画。 + +# 参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/JSUI/ClickableJsDemo) diff --git a/JSUI/ClickableJsDemo/build.gradle b/JSUI/ClickableJsDemo/build.gradle index ece154750a0fd2bc4bfaaf437945f86e10851f80..c749a652c0c6152731a11e2e2fe7de9364d87b17 100644 --- a/JSUI/ClickableJsDemo/build.gradle +++ b/JSUI/ClickableJsDemo/build.gradle @@ -19,7 +19,7 @@ buildscript { } } dependencies { - classpath 'com.huawei.ohos:hap:2.4.5.5' + classpath 'com.huawei.ohos:hap:3.0.1.4' classpath 'com.huawei.ohos:decctest:1.2.5.1' } } diff --git a/JSUI/ClickableJsDemo/figures/IMG_20211208_192923.jpg b/JSUI/ClickableJsDemo/figures/IMG_20211208_192923.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c0b44cbe7726489d5e798e4898456d3814b61196 Binary files /dev/null and b/JSUI/ClickableJsDemo/figures/IMG_20211208_192923.jpg differ diff --git "a/JSUI/ClickableJsDemo/figures/\345\217\226\347\211\210\346\234\254.png" "b/JSUI/ClickableJsDemo/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/JSUI/ClickableJsDemo/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/JSUI/ClickableJsDemo/figures/\346\210\252\345\233\276.png" "b/JSUI/ClickableJsDemo/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/JSUI/ClickableJsDemo/figures/\346\210\252\345\233\276.png" differ diff --git "a/JSUI/ClickableJsDemo/figures/\346\210\252\345\233\2761.png" "b/JSUI/ClickableJsDemo/figures/\346\210\252\345\233\2761.png" new file mode 100644 index 0000000000000000000000000000000000000000..1f1a918debf840eb77dec2302080d7b7e8889803 Binary files /dev/null and "b/JSUI/ClickableJsDemo/figures/\346\210\252\345\233\2761.png" differ diff --git "a/JSUI/ClickableJsDemo/figures/\347\254\254\344\270\200\345\274\240\345\233\276.png" "b/JSUI/ClickableJsDemo/figures/\347\254\254\344\270\200\345\274\240\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..e71dded5e36d004251d0d8e243164a240419353d Binary files /dev/null and "b/JSUI/ClickableJsDemo/figures/\347\254\254\344\270\200\345\274\240\345\233\276.png" differ diff --git "a/JSUI/ClickableJsDemo/figures/\347\254\254\344\270\211\345\274\240.jpg" "b/JSUI/ClickableJsDemo/figures/\347\254\254\344\270\211\345\274\240.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..c2d1b7cbbcedf84593fda9819ac205777c4aebcb Binary files /dev/null and "b/JSUI/ClickableJsDemo/figures/\347\254\254\344\270\211\345\274\240.jpg" differ diff --git "a/JSUI/ClickableJsDemo/figures/\347\254\254\344\272\214\345\274\240\345\233\276.png" "b/JSUI/ClickableJsDemo/figures/\347\254\254\344\272\214\345\274\240\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..5e0ee5c9d4a1aa2481bcc3dd2ef0f1fce794260e Binary files /dev/null and "b/JSUI/ClickableJsDemo/figures/\347\254\254\344\272\214\345\274\240\345\233\276.png" differ diff --git "a/JSUI/ClickableJsDemo/figures/\347\254\254\345\233\233\345\274\240.jpg" "b/JSUI/ClickableJsDemo/figures/\347\254\254\345\233\233\345\274\240.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..402c52af49483927961d3b173b439845a6abf694 Binary files /dev/null and "b/JSUI/ClickableJsDemo/figures/\347\254\254\345\233\233\345\274\240.jpg" differ diff --git a/JSUI/ClickableJsDemo/public_sys-resources/icon-caution.gif b/JSUI/ClickableJsDemo/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/ClickableJsDemo/public_sys-resources/icon-caution.gif differ diff --git a/JSUI/ClickableJsDemo/public_sys-resources/icon-danger.gif b/JSUI/ClickableJsDemo/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/ClickableJsDemo/public_sys-resources/icon-danger.gif differ diff --git a/JSUI/ClickableJsDemo/public_sys-resources/icon-note.gif b/JSUI/ClickableJsDemo/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/JSUI/ClickableJsDemo/public_sys-resources/icon-note.gif differ diff --git a/JSUI/ClickableJsDemo/public_sys-resources/icon-notice.gif b/JSUI/ClickableJsDemo/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/JSUI/ClickableJsDemo/public_sys-resources/icon-notice.gif differ diff --git a/JSUI/ClickableJsDemo/public_sys-resources/icon-tip.gif b/JSUI/ClickableJsDemo/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/JSUI/ClickableJsDemo/public_sys-resources/icon-tip.gif differ diff --git a/JSUI/ClickableJsDemo/public_sys-resources/icon-warning.gif b/JSUI/ClickableJsDemo/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/ClickableJsDemo/public_sys-resources/icon-warning.gif differ diff --git a/JSUI/DialogDemo/README.md b/JSUI/DialogDemo/README.md index b2935b913c4718bd923c30c5494e2511d0f56351..604675a1dca0552f189d539cd727177a4999635b 100644 --- a/JSUI/DialogDemo/README.md +++ b/JSUI/DialogDemo/README.md @@ -1,3 +1,386 @@ # DialogDemo -简介 -• 此Demo使用JS UI中的dialog组件,实现了dialog的几种常用的效果,点击界面上不同的button呈现不同样式的dialog。 +# 介绍 + +OpenHarmony的ArkUI(基于JS扩展的类Web开发范式)提供了常用的接口和组件,开发者可以根据实际场景和开发需求,选用不同的组件和接口。本篇Codelab,我们将一起开启ArkUI(基于JS扩展的类Web开发范式)容器组件的学习之路。本教程给大家分享的内容是容器组件dialog的使用。 + +本篇Codelab通过一个简单的样例,实现了dialog的几种常用的效果,点击不同的button呈现不同的样式的dialog。效果如下图所示,开发者还可以根据自己的需求添加不同的效果。 + +![](figures/成品2-00_00_00-00_00_30.gif) + + +# 相关概念 + +**[dialog组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-container-dialog.md)**:自定义弹窗容器组件。 + +**[button组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-button.md)**:按钮组件。 + +**[div组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-container-div.md)**:基础容器组件,用作页面结构的根节点或将内容进行分组。 + +**[text组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-text.md)**:文本组件,用于呈现一段信息。 + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 将组件添加到布局中 + +- [button组件](#section1648574312326) +- [dialog组件](#section1393961711172) + +我们需要完成程序页面的新建和设计,并将程序使用到的input组件添加到布局文件index.hml中。在完成新建项目后,我们看到系统自动创建了pages.index目录,打开index.hml文件,开始进行页面设计。 + +打开index.hml文件,里面有默认代码如下: + +``` +
+ + {{ $t('strings.hello') }} {{ title }} + +
+``` + +## button组件 + +开发者可以删除默认代码跟着接下来的步骤一起开发,实现如下界面效果。 + +![](figures/1.png) + +从上面布局效果图可以看到,界面主要由button组成,我们先在index.hml中添加button组件,并添加onclick事件,代码如下: + +``` +
+
+ + + + + +
+
+``` + +## dialog组件 + +因为上面添加了5个button,根据效果图点击不同的button会呈现不同的dialog,所以我们接下来将在index.hml中添加5个dialog,代码如下所示: + +``` +
+
+ + + + + +
+ + +
+
+ AlertDialog +
+
+ +
+
+
+ + +
+
+ ConfirmDialog +
+
+ + +
+
+
+ + +
+ + loading... +
+
+ + +
+
+ PromptDialog +
+ + +
+ + +
+
+
+ + +
+ Downloading... +
+ +
+ Image {{ percent / 10 }} of 10 +
+
+ +
+``` + +# 为页面设计样式 + +在这此步骤中,我们将一起为写好的页面添加样式,上面所有的组件都定义了class属性,它对应的样式都定义在index.css中,有关css更多的知识可以参考[CSS语法参考](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-framework-syntax-css.md)。 + +这部分定义了整个页面中各个组件的样式,在index.css中先添加如下代码: + +``` +.doc-page { + height: 100%; + flex-direction: column; + background-color: #E3f8F9; + justify-content: center; + align-items: center; +} + +.btn-div { + width: 100%; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.btn { + background-color: #17A98E; + margin-top: 15px; + width: 80%; + font-weight: bold; +} + +.btn-text { + color: #000000; + font-weight: bold; + font-size: 39px; +} + +.dialog-main { + width: 80%; + margin-bottom: 40%; +} + +.dialog-div { + flex-direction: column; + align-items: center; +} + +.inner-txt { + height: 120px; + flex-direction: column; + align-items: center; + justify-content: space-around; +} + +.inner-btn { + height: 80px; + justify-content: center; + align-items: center; +} + +.alert-inner-txt { + height: 120px; + flex-direction: column; + align-items: center; + justify-content: space-around; +} + +.alert-inner-btn { + height: 80px; + justify-content: space-around; + align-items: center; +} + +.alert-dialog { + width: 80%; + margin-bottom: 40%; +} +``` + +# 为组件添加相应事件 + +我们已经为样例定义好了布局和样式,接下来,我们一起来完成整个样例的最后一步:实现点击不同的button呈现不同dialog效果的功能。 + +首先我们了解一下dialog主要有哪些API,如下所示: + +dialog支持如下事件: + + + + + + + + + + + + + +

名称

+

参数

+

描述

+

cancel

+

-

+

用户点击非dialog区域触发取消弹窗时触发的事件。

+
+ + + +dialog支持如下方法: + + + + + + + + + + + + + + + + + +

名称

+

参数

+

描述

+

show

+

-

+

弹出对话框

+

close

+

-

+

关闭对话框

+
+ + + +我们已经在之前的步骤中给button分别绑定了click事件,下面我们将实现这些事件调用的方法,在index.js中添加如下代码: + +``` +import prompt from '@system.prompt'; + +export default { + data: { + percent: 0, + interval: '' + }, + showAlert() { + this.$element('alertDialog').show(); + }, + showConfirm() { + this.$element('confirmDialog').show(); + }, + showLoading() { + const options = { + duration: 800, + easing: 'linear', + iterations: 'Infinity' + }; + const frames = [ + { + transform: { + rotate: '0deg' + } + }, + { + transform: { + rotate: '360deg' + } + } + ]; + this.animation = this.$element('loading-img').animate(frames, options); + this.$element('loadingDialog').show(); + this.animation.play(); + }, + showPrompt() { + this.$element('promptDialog').show(); + }, + showProgress() { + const that = this; + that.percent = 0; + this.$element('progressDialog').show(); + this.interval = setInterval(function() { + that.percent += 10; + if (that.percent >= 100) { + clearInterval(that.interval); + } + }, 500); + }, + confirmClick(id) { + this.$element(id).close(); + prompt.showToast({ + message: 'confirm clicked' + }); + }, + cancelClick(id) { + this.$element(id).close(); + prompt.showToast({ + message: 'cancel clicked' + }); + }, + onCancel(){ + clearInterval(this.interval); + } +}; +``` + +# 恭喜你 + +在本篇Codelab中,我们主要为大家讲解了如下JS组件 + +- dialog + +通过一个代码示例,实现dialog的不同呈现效果,从布局、样式、响应事件三个层面,逐步为大家进行代码讲解。希望通过本教程,各位开发者可以对以上组件具有更深刻的认识。 + +# 参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/JSUI/DialogDemo) diff --git a/JSUI/DialogDemo/entry/build.gradle b/JSUI/DialogDemo/entry/build.gradle index cccb71cae91018743841ab76aeb19c595f4ed847..1587dd1948941f3eaaf092ae6cae7969cb6895ff 100644 --- a/JSUI/DialogDemo/entry/build.gradle +++ b/JSUI/DialogDemo/entry/build.gradle @@ -1,9 +1,9 @@ apply plugin: 'com.huawei.ohos.hap' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 defaultConfig { - compatibleSdkVersion 6 + compatibleSdkVersion 7 } buildTypes { release { @@ -13,11 +13,9 @@ ohos { } } } - - supportSystem "standard" } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) - testImplementation 'junit:junit:4.13' + testImplementation 'junit:junit:4.13.1' } diff --git a/JSUI/DialogDemo/entry/src/main/config.json b/JSUI/DialogDemo/entry/src/main/config.json index 34d1702a5ef29c4e0b76e35df47e7303683a9985..b255a44e2c0186387b83734b63dabe47b8d130d9 100644 --- a/JSUI/DialogDemo/entry/src/main/config.json +++ b/JSUI/DialogDemo/entry/src/main/config.json @@ -34,6 +34,7 @@ } ], "orientation": "unspecified", + "visible": true, "name": "com.huawei.dialogdemo.MainAbility", "icon": "$media:icon", "srcPath": "default", diff --git a/JSUI/DialogDemo/figures/1.png b/JSUI/DialogDemo/figures/1.png new file mode 100644 index 0000000000000000000000000000000000000000..292e48419a01ff088b3bdfacc7e025039d66c731 Binary files /dev/null and b/JSUI/DialogDemo/figures/1.png differ diff --git "a/JSUI/DialogDemo/figures/\345\217\226\347\211\210\346\234\254.png" "b/JSUI/DialogDemo/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/JSUI/DialogDemo/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/JSUI/DialogDemo/figures/\346\210\220\345\223\2012-00_00_00-00_00_30.gif" "b/JSUI/DialogDemo/figures/\346\210\220\345\223\2012-00_00_00-00_00_30.gif" new file mode 100644 index 0000000000000000000000000000000000000000..8bb4ecf393e2b31b4919b3181198e2d041205d1b Binary files /dev/null and "b/JSUI/DialogDemo/figures/\346\210\220\345\223\2012-00_00_00-00_00_30.gif" differ diff --git "a/JSUI/DialogDemo/figures/\346\210\252\345\233\276.png" "b/JSUI/DialogDemo/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/JSUI/DialogDemo/figures/\346\210\252\345\233\276.png" differ diff --git a/JSUI/DialogDemo/public_sys-resources/icon-caution.gif b/JSUI/DialogDemo/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/DialogDemo/public_sys-resources/icon-caution.gif differ diff --git a/JSUI/DialogDemo/public_sys-resources/icon-danger.gif b/JSUI/DialogDemo/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/DialogDemo/public_sys-resources/icon-danger.gif differ diff --git a/JSUI/DialogDemo/public_sys-resources/icon-note.gif b/JSUI/DialogDemo/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/JSUI/DialogDemo/public_sys-resources/icon-note.gif differ diff --git a/JSUI/DialogDemo/public_sys-resources/icon-notice.gif b/JSUI/DialogDemo/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/JSUI/DialogDemo/public_sys-resources/icon-notice.gif differ diff --git a/JSUI/DialogDemo/public_sys-resources/icon-tip.gif b/JSUI/DialogDemo/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/JSUI/DialogDemo/public_sys-resources/icon-tip.gif differ diff --git a/JSUI/DialogDemo/public_sys-resources/icon-warning.gif b/JSUI/DialogDemo/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/DialogDemo/public_sys-resources/icon-warning.gif differ diff --git a/JSUI/InputApplication/README.md b/JSUI/InputApplication/README.md index 505640dbfe350a9b8ec332bcc327f370e5dc9c64..55fad8775436924e6ed7b35af537dfa0bd9cc9b6 100644 --- a/JSUI/InputApplication/README.md +++ b/JSUI/InputApplication/README.md @@ -1,3 +1,376 @@ # InputApplication -简介 -• 此Demo使用JS UI中的input组件,实现输入框和表单提交。您可以在input输入框输入内容,长按input输入框对输入内容进行翻译、分享、查找等操作,点击提交按钮时对必填项进行校验。 \ No newline at end of file +# 介绍 + +- [应用场景](#section225718574575) + +OpenHarmony ArkUI(基于JS扩展的类Web开发范式)框架提供了常用的接口和组件,开发者可以根据实际场景和开发需求,选用不同的组件和接口。本篇Codelab,我们将一起开启ArkUI(基于JS扩展的类Web开发范式)基础组件的学习之路。本教程是基础组件之input组件的使用。 + +在本教程中,我们将会通过一个简单的样例,使用input的text、email、date、number、password、button、checkbox、radio等类型实现一个form表单的提交效果。效果如下图所示,开发者还可以根据自己的需求添加不同的效果。 + +![](figures/IMG_20211213_141801.jpg) + +## 应用场景 + +- 社交、金融类应用涉及到用户注册等需要用户提交表单的场景。 + +# 相关概念 + +**[input组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-input.md)**:交互式组件,包括单选框、多选框、按钮和单行文本输入框。 + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 将组件添加到布局文件中 + +- [input组件](#section1648574312326) + +在这个任务中,我们需要完成程序页面的新建和设计,并将程序使用到的input组件添加到布局文件index.hml中。在完成任务一新建项目后生成的默认目录pages.index下,打开index.hml文件,开始进行页面设计。 + +打开index.hml文件,默认代码如下: + +``` +
+ + {{ $t('strings.hello') }} {{ title }} + +
+``` + +代码使用div组件和text组件来共同呈现文本显示的效果,其中div属于[基础容器](https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-container-div-0000000000611484),用作页面结构的根节点或将内容进行分组;text是[文本组件](https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-basic-text-0000000000611633),用于呈现一段信息。有关这两个组件更多的知识,我们会在其他Codelab中为大家讲解。 + +## input组件 + +开发者可以删除index.hml文件中的默认代码,根据下述步骤一起进行开发,整个布局文件使用div组件将页面进行划分,页面从上到下包括:text、password、email、date、number、radio、checkbox、button类型,页面如下: + +![](figures/IMG_20211213_141801-0.jpg) + +上图的页面hml示例代码如下: + +``` +
+
+ input 表单 +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + + 女 + +
+
+
+ +
+ + 游泳 + + 健身 + + 足球 + + 篮球 +
+
+ + + +
+``` + +# 为页面设计样式 + +- [input组件部分样式](#section165281839182814) + +在这个任务中,我们将一起为写好的页面添加样式,上面所有的组件,我们都定义了class属性,它对应的样式都定义在index.css中,有关css更多的知识可以参考[CSS语法参考](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-framework-syntax-css.md)。 + +## input组件部分样式 + +这部分定义了输入框、单选、多选组件的样式。删掉默认代码后,在index.css中先添加如下代码: + +``` +.container { + flex-direction: column; + align-items: center; +} +.input-form { + width: 100%; + justify-content: center; + margin-top: 10px; + margin-bottom: 10px; +} +.form-text { + font-size: 20px; +} +.row { + width: 98%; + margin-top: 5px; + flex-direction: row; +} +.label { + font-size: 13px; + width: 120px; + text-align: right; +} +.input-block { + width: 100%; +} +.input { + width: 90%; + font-size: 12px; +} +.password-tip { + font-size: 10px; +} +.sex { + font-size: 10px; + margin-right: 10px; +} +.favorite { + font-size: 10px; +} +.button { + margin-top: 70px; + width: 150px; + background-color: #17A98E; +} +``` + +# 为组件添加响应事件 + +- [数据定义](#section191691020144313) +- [事件](#section2363155714436) + +## 数据定义 + +在前面的步骤中,我们已经提到了布局中组件初始值的定义,在index.js中首先添加如下代码: + +``` +import prompt from '@system.prompt'; + +export default { + data: { + require: '/common/images/require.png', + username: '', + password: '', + password2: '', + email: '', + date: '', + height: '', + favorite: [], + list: [{icon: '/common/images/require.png', content: '选项0'}, + {icon: '/common/images/require.png', content: '选项1'}] + }, +} +``` + +这些值的具体含义,可以参考如下表格: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

key

+

description

+

require

+

表示必填项的红色标识

+

username

+

用户名

+

password

+

密码

+

passwordConfirm

+

确认密码

+

email

+

电子邮箱

+

date

+

出生日期

+

height

+

身高

+

hobby

+

爱好

+

list

+

身高input输入框中menuoptions事件的值

+
+ + + +## 事件 + +接下来在export default的data对象后面继续添加事件代码,当文本框内容改变、长按文本框时触发如下事件: + +``` +// 文本框内容发生变化 +change(e) { + var idName = e.target.id; + if (idName === "username") { + this.username = e.value; + } else if (idName === "password") { + this.password = e.value; + } else if (idName === "password2") { + this.password2 = e.value; + } else if (idName === "email") { + this.email = e.value; + } else if (idName === "date") { + this.date = e.value; + } else if (idName === "height") { + this.height = e.value; + } +}, +// 复选框修改 +checkboxOnChange(e) { + var value = e.target.attr.value + if (e.checked) { + this.favorite.push(value); + } else { + this.favorite.splice(this.favorite.findIndex(e => e === value), 1); + } +}, +// 提交 +buttonClick() { + if (this.username === "") { + this.showPrompt('用户名不能为空'); + } else if (this.password === "") { + this.showPrompt('密码不能为空'); + } else if (this.password !== "" && this.password !== this.password2) { + this.showPrompt('两次密码输入不一致'); + } else if (this.email === "") { + this.showPrompt('邮箱不能为空'); + } else if (this.favorite.length === 0) { + this.showPrompt('请至少选择一个爱好'); + } else { + this.showPrompt('提交成功'); + } +}, +//弹框 +showPrompt(msg) { + prompt.showToast({ + message: msg, + duration: 3000, + }); +}, +// 进行文本选择操作后文本选择弹窗会出现翻译按钮 +translate(e) { + this.showPrompt(e.value); +}, +//进行文本选择操作后文本选择弹窗会出现分享按钮 +share(e) { + this.showPrompt(e.value); +}, +// 进行文本选择操作后文本选择弹窗会出现查询按钮 +search(e) { + this.showPrompt(e.value); +}, +// 用户在文本选择操作后,点击菜单项后触发该回调 +optionselect(e) { + this.showPrompt("选项" + e.index + ": " + e.value); +} +``` + +到此我们已经完成了所有的任务和代码的编写。 + +>![](public_sys-resources/icon-note.gif) **说明:** +>样例中我们使用了一张input输入框必填标识图片,它放在js/default/common.images目录下,命名为require.png + +# 恭喜你 + +在本篇Codelab中,我们主要为大家讲解了如下ArkUI(基于JS扩展的类Web开发范式)基础组件 + +- input + +通过一个代码示例,实现input组件表单,从布局、样式、响应事件三个层面,逐步为大家进行代码讲解。希望通过本教程,各位开发者可以对以上基础组件具有更深刻的认识。 + +# 参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/JSUI/InputApplication) diff --git a/JSUI/InputApplication/entry/src/main/config.json b/JSUI/InputApplication/entry/src/main/config.json index 0aba403d7c78d96e1043d52a2fcdf40ab1fde36f..183065c492c1aa35d1ca300a794f74cae437fc1f 100644 --- a/JSUI/InputApplication/entry/src/main/config.json +++ b/JSUI/InputApplication/entry/src/main/config.json @@ -34,7 +34,10 @@ } ], "orientation": "unspecified", + "visible": true, + "srcPath": "default", "name": "com.huawei.inputapplication.MainAbility", + "srcLanguage": "js", "icon": "$media:icon", "description": "$string:mainability_description", "formsEnabled": false, diff --git a/JSUI/InputApplication/figures/IMG_20211213_141801-0.jpg b/JSUI/InputApplication/figures/IMG_20211213_141801-0.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1f2b72c774b81d87f7f88918a3da75aaad9d020e Binary files /dev/null and b/JSUI/InputApplication/figures/IMG_20211213_141801-0.jpg differ diff --git a/JSUI/InputApplication/figures/IMG_20211213_141801.jpg b/JSUI/InputApplication/figures/IMG_20211213_141801.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1f2b72c774b81d87f7f88918a3da75aaad9d020e Binary files /dev/null and b/JSUI/InputApplication/figures/IMG_20211213_141801.jpg differ diff --git "a/JSUI/InputApplication/figures/\345\217\226\347\211\210\346\234\254.png" "b/JSUI/InputApplication/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/JSUI/InputApplication/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/JSUI/InputApplication/figures/\346\210\252\345\233\276.png" "b/JSUI/InputApplication/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/JSUI/InputApplication/figures/\346\210\252\345\233\276.png" differ diff --git a/JSUI/InputApplication/public_sys-resources/icon-caution.gif b/JSUI/InputApplication/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/InputApplication/public_sys-resources/icon-caution.gif differ diff --git a/JSUI/InputApplication/public_sys-resources/icon-danger.gif b/JSUI/InputApplication/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/InputApplication/public_sys-resources/icon-danger.gif differ diff --git a/JSUI/InputApplication/public_sys-resources/icon-note.gif b/JSUI/InputApplication/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/JSUI/InputApplication/public_sys-resources/icon-note.gif differ diff --git a/JSUI/InputApplication/public_sys-resources/icon-notice.gif b/JSUI/InputApplication/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/JSUI/InputApplication/public_sys-resources/icon-notice.gif differ diff --git a/JSUI/InputApplication/public_sys-resources/icon-tip.gif b/JSUI/InputApplication/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/JSUI/InputApplication/public_sys-resources/icon-tip.gif differ diff --git a/JSUI/InputApplication/public_sys-resources/icon-warning.gif b/JSUI/InputApplication/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/InputApplication/public_sys-resources/icon-warning.gif differ diff --git a/JSUI/JSCanvasComponet/README.md b/JSUI/JSCanvasComponet/README.md index 6af739c52609dc0da161a7f5d0915693141fb768..a175f3682387175a629d92a74b87b1dd16606173 100644 --- a/JSUI/JSCanvasComponet/README.md +++ b/JSUI/JSCanvasComponet/README.md @@ -1,3 +1,357 @@ -# JSCanvasCompont +# 介绍 + +本教程为您展示如何使用自定义组件实现圆形抽奖转盘功能。当系统提供的组件无法满足设计需求时,您可以创建自定义组件,根据设计需求自定义组件的属性及响应事件,并绘制组件。圆形抽奖转盘是两个自定义图层中实现绘制,通过canvas完成绘制任务,最终与组件的其它图层合成在一起呈现在界面中。效果图如下: + +**图 1** +![](figures/zh-cn_image_0000001237353117.gif "zh-cn_image_0000001237353117") + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 代码结构解读 + +代码结构解读 + +本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在最后的参考中提供下载方式,接下来我们会用一小节来讲解整个工程的代码结构: + +![](figures/zh-cn_image_0000001238220835.png) + +- pages:用于存放所有页面的目录。 + - common:文件夹存放一些公共的资源,比如图片。 + - index:构成自定义组件界面,包括index.hml布局文件,index.css样式文件,index.js逻辑处理文件。 + + +- config.json:配置文件。 + +# 基本步骤 + +在index.hml布局界面中添加canvas组件,根据需求绘制需要的图形。 + +``` + + + + + + +``` + +在index.js文件通过onDraw方法中进行绘制。 + +``` +draw() { + // 将画布沿X、Y轴平移指定距离 + this.ctx.translate(this.centerX + 10, this.centerY); + // 画外部圆盘的花瓣 + this.drawFlower(); + // 画外部圆盘、小圈圈、五角星 + this.drawOutCircleAndFive(); + // 画内部扇形抽奖区域 + this.drawInnerArc(); + // 画内部扇形区域文字 + this.drawArcText(); + // 画内部扇形区域奖品对应的图片 + this.drawImage(); + // 画中心圆盘和指针 + this.drawCenter(); +}, +``` +# 画外部圆盘 +1. 画外部圆盘的花瓣:通过调用canvas的rotate\(\)方法,将画布旋转指定角度。通过调用canvas的save\(\)和restore\(\)方法,使画布保存最新的绘制状态。根据想要绘制的花瓣个数,改变旋转角度,循环画出花瓣效果。 + + ``` + drawFlower() { + let beginAngle = this.startAngle + this.avgAngle; + const radius = this.centerX - this.padding; + for (let i = 0; i < this.count; i++) { + this.ctx.save(); + this.ctx.beginPath(); + this.ctx.fillStyle = '#F3B468'; + this.ctx.rotate(beginAngle * Math.PI / 180); + this.ctx.arc(-radius / 2, radius / 2, radius / 2, 0, Math.PI * 2); + this.ctx.fill(); + + this.ctx.beginPath(); + this.ctx.fillStyle = '#E588B9'; + this.ctx.arc(-radius / 2, radius / 2, (radius - this.padding) / 2, 0, Math.PI * 2); + beginAngle += this.avgAngle; + this.ctx.fill(); + this.ctx.restore(); + } + } + ``` + +2. 画外部圆盘边上的小圈圈和五角星:接下来一个for循环,且角度每次递增\(this.avgAngle / 3\),就是绘制圆环上的小圈圈和五角星了。因为是交替绘制五角星和小圈圈,所以用一个条件判断语句去绘制。 + + ``` + drawOutCircleAndFive() { + this.ctx.beginPath(); + this.ctx.fillStyle = '#ED6D56'; + this.ctx.arc(0, 0, this.centerX - this.padding, 0, Math.PI * 2); + this.ctx.fill(); + let beginAngle = this.startAngle + this.avgAngle; + for (let i = 0; i < this.count * 3; i++) { + this.ctx.save(); + if (0 === i % 2) { + // 画小圆圈 + this.ctx.beginPath(); + this.ctx.rotate(beginAngle * Math.PI / 180); + this.ctx.fillStyle = '#FFFFFF'; + this.ctx.arc(this.centerX - this.padding - this.padding / 2, 0, 5, 0, Math.PI * 2); + this.ctx.fill(); + } else { + // 画五角星 + this.paintFiveStart(beginAngle); + } + beginAngle = beginAngle + this.avgAngle / 3; + this.ctx.restore(); + } + }, + ``` + +3. 画五角星:通过计算获取到五角星的5个顶点位置(计算依据:五角星每个角的角度为36°,然后根据三角函数即可算出各个点的坐标),再使用canvas的fill方法将5个顶点通过画线连接在一起,就完成了五角星的绘制。 + + ``` + // 画五角星 + paintFiveStart(beginAngle) { + // 画五角星的path + this.ctx.beginPath(); + this.ctx.rotate(beginAngle * Math.PI / 180); + this.ctx.fillStyle = '#FFFF00'; + const points = this.fivePoints(this.centerX - this.padding - this.padding / 2, 0, this.padding / 2); + for (let i = 0; i < points.length - 1; i = i + 2) { + this.ctx.lineTo(points[i], points[i + 1]); + } + this.ctx.closePath(); + this.ctx.fill(); + }, + + // 获取五角星的五个顶点 + fivePoints(pointXa, pointYa, sideLength) { + const radian = 18 * Math.PI / 180; + const pointXb = pointXa + sideLength / 2; + const num = sideLength * Math.sin(radian); + const pointXc = pointXa + num; + const pointXd = pointXa - num; + const pointXe = pointXa - sideLength / 2; + const pointYb = pointYa + Math.sqrt(Math.pow(pointXc - pointXd, 2) - Math.pow(sideLength / 2, 2)); + const pointYc = pointYa + Math.cos(radian) * sideLength; + const pointYd = pointYc; + const pointYe = pointYb; + const points = [pointXa, pointYa, pointXd, pointYd, pointXb, pointYb, + pointXe, pointYe, pointXc, pointYc, pointXa, pointYa]; + return points; + }, + ``` +# 画内部扇形抽奖区域 +1. 画抽奖区域扇形:使用canvas的arc方法绘制弧,接下来一个for循环,且角度每次递增this.startAngle,然后不断更改弧线的起始弧度\(this.startAngle \* Math.PI / 180\)和弧线的终止弧度\(this.startAngle + this.avgAngle\) \* Math.PI / 180。最后fill\(\)方法对路径进行填充。 + + ``` + drawInnerArc() { + const radius = this.centerX - this.padding * 2; + for (let i = 0; i < this.count; i++) { + this.ctx.beginPath(); + this.ctx.fillStyle = this.colors[i]; + this.ctx.arc(0, 0, radius, this.startAngle * Math.PI / 180, (this.startAngle + this.avgAngle) * Math.PI / 180); + this.ctx.lineTo(0, 0); + this.ctx.fill(); + this.startAngle += this.avgAngle; + } + }, + ``` + +2. 画抽奖区域文字:textArrays 表示需要绘制文本数组集合,接下来一个for循环,通过drawCircularText\(\)方法绘制每组文字。drawCircularText\(\)方法接收三个参数,分别是字符串,起始弧度和终止弧度。绘制文本前需要设置每个字母占的弧度angleDecrement,然后设置水平和垂直的偏移量。垂直偏移量\( circleText.y - Math.sin\(angle\) \* radius\)就是朝着圆心移动的距离;水平偏移量,就是顺时针去旋转,水平偏移\(circleText.x + Math.cos\(angle\) \* radius\),是为了让文字在当前弧范围文字居中。最后使用canvas的fillText方法绘制文本。 + + ``` + drawArcText() { + this.ctx.textAlign = 'center'; + this.ctx.textBaseLine = 'middle'; + this.ctx.fillStyle = '#EA86A4'; + this.ctx.font = this.padding + 'px sans-serif'; + const textArrays = ['恭喜发财', '华为耳机', '华为手机', '恭喜发财', '华为平板', '华为手表']; + for (let i = 0; i < this.count; i++) { + this.drawCircularText(textArrays[i], (this.startAngle + this.avgAngle * 3 / 4) * Math.PI / 180, + (this.startAngle + this.avgAngle / 4) * Math.PI / 180); + this.startAngle += this.avgAngle; + } + }, + drawCircularText(textString, startAngle, endAngle) { + const circleText = { + x: 0, + y: 0, + radius: this.centerX - this.padding * 2 + }; + // 圆的半径 + const radius = circleText.radius - circleText.radius / 5; + // 每个字母占的弧度 + const angleDecrement = (startAngle - endAngle) / (textString.length - 1); + let angle = parseFloat(startAngle); + let index = 0; + let character; + + while (index < textString.length) { + character = textString.charAt(index); + this.ctx.save(); + this.ctx.beginPath(); + //circleText.x 文本 Math.cos(angle) * radius + this.ctx.translate(circleText.x + Math.cos(angle) * radius, circleText.y - Math.sin(angle) * radius); + this.ctx.rotate(Math.PI / 2 - angle); + this.ctx.fillText(character, 0, 0); + angle -= angleDecrement; + index++; + this.ctx.restore(); + } + }, + ``` + +3. 画抽奖区域文字对应图片:使用canvas的drawImage方法绘制抽奖区域文字对应图片,该方法接收三个参数,分别是图片资源,对象的左上角和右上角。 + + ``` + drawImage() { + let beginAngle = this.startAngle + this.avgAngle / 2; + const imageSrc = ['common/images/watch.png', 'common/images/tablet.png', 'common/images/thanks.png', + 'common/images/phone.png', 'common/images/headset.png', 'common/images/thanks.png']; + const img = new Image(); + for (let i = 0; i < this.count; i++) { + img.src = imageSrc[i]; + this.ctx.save(); + this.ctx.beginPath(); + this.ctx.rotate(beginAngle * Math.PI / 180); + this.ctx.drawImage(img, this.centerX / 3, -48 / 2); + beginAngle += this.avgAngle; + this.ctx.restore(); + } + }, + ``` +# 画中心圆盘和指针 + +1. 画中心圆盘大指针:首先确定要移动的三个点的坐标\(-centerX / nine, 0\)、\(centerX / nine, 0\)、\(0F, -centerX / 3\),通过canvas的fill方法去绘制指针。 + + ``` + centerCtx.beginPath(); + centerCtx.fillStyle = '#F6C8D8'; + centerCtx.moveTo(-this.centerX / nine, 0); + centerCtx.lineTo(this.centerX / nine, 0); + centerCtx.lineTo(0, -this.centerX / 3); + centerCtx.closePath(); + centerCtx.fill(); + ``` + +2. 画内部大圆和小圆:在圆盘圆心处,绘制两个半径分别为centerX / 7 + padding / 2、centerX / 7的中心圆盘。 + + ``` + // 画内部大圆 + centerCtx.beginPath(); + centerCtx.fillStyle = '#F6C8D8'; + centerCtx.arc(0, 0, this.centerX / 7 + this.padding / 2, 0, Math.PI * 2); + centerCtx.fill(); + // 画内部小圆 + centerCtx.beginPath(); + centerCtx.fillStyle = '#FFFFFF'; + centerCtx.arc(0, 0, this.centerX / 7, 0, Math.PI * 2); + centerCtx.fill(); + ``` + +3. 画中心圆盘小指针:与步骤1中画中心圆盘大指针类似,通过canvas的fill方法去绘制中心圆盘小指针。 + + ``` + centerCtx.beginPath(); + centerCtx.fillStyle = '#FFFFFF'; + centerCtx.moveTo(-this.centerX / 18, 0); + centerCtx.lineTo(this.centerX / 18, 0); + centerCtx.lineTo(0, -this.centerX / 3 + this.padding / 2); + centerCtx.closePath(); + centerCtx.fill(); + ``` + +4. 画中心圆弧文字:首先设置需要绘制文本的样式,再通过canvas的fillText方法绘制中心文本。 + + ``` + const text = '开始'; + centerCtx.textAlign = 'center'; + centerCtx.fillStyle = '#EA86A4'; + centerCtx.font = this.padding - 10 + 'px sans-serif'; + centerCtx.beginPath(); + centerCtx.fillText(text, 0, this.ctx.measureText(text).width / 5); + ``` +# 实现抽奖功能 + +1. 获取屏幕上点击的坐标,当点击的范围在中心圆盘区域时,圆形转盘开始转动抽奖。 + + ``` + touchStart(event) { + // 获取屏幕上点击的坐标 + const floatX = event.touches[0].globalX; + const floatY = event.touches[0].globalY; + const radius = this.centerX / 7 + this.padding / 2; + const isScopeX = this.centerX - radius < floatX && this.centerX + radius > floatX; + const isScopeY = this.centerY - radius < floatY && this.centerY + radius > floatY; + if (isScopeX && isScopeY && this.playState !== 'running') { + this.startAnimator(); + } + }, + ``` + +2. 圆形转盘开始转动抽奖:给转盘指定一个随机的转动角度randomAngle,保证每次转动的角度是随机的\(即每次抽到的奖品也是随机的\)。动画结束后,转盘停止转动(即抽奖结束),会弹出抽中的奖品提示信息。 + + ``` + startAnimator() { + const angle = 270; + const randomAngle = Math.random() * this.circle; + this.startAngle = this.circle * 5 - randomAngle + angle; + if (this.infinite === 0) { + this.infinite = -1; // 永久旋转 + } + setTimeout(() => { + this.infinite = 0; + this.playState = 'pause'; + this.showPrizeMessage(randomAngle); + }, 4000); + + this.rotateDegree = this.startAngle; + this.playState = 'running'; + }, + ``` + +# 恭喜你 + +通过本教程的学习,您已学会了如何使用自定义组件实现圆形抽奖转盘。 + +# 参考 + +等待代码开源 + + + + + + + + -本篇Codelab将使用JS语言进行开发,做一个自定义组件绘制转盘的动画。 \ No newline at end of file diff --git a/JSUI/JSCanvasComponet/build.gradle b/JSUI/JSCanvasComponet/build.gradle index 34c817dd5b1c637230b7f468063913f5509976ad..c2c8bbaed13747b913f19cef893f515bc32d02a7 100644 --- a/JSUI/JSCanvasComponet/build.gradle +++ b/JSUI/JSCanvasComponet/build.gradle @@ -3,7 +3,8 @@ apply plugin: 'com.huawei.ohos.app' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 + supportSystem "standard" } buildscript { @@ -16,8 +17,8 @@ buildscript { } } dependencies { - classpath 'com.huawei.ohos:hap:2.4.5.5' - classpath 'com.huawei.ohos:decctest:1.2.5.1' + classpath 'com.huawei.ohos:hap:3.0.3.4' + classpath 'com.huawei.ohos:decctest:1.2.6.0' } } diff --git a/JSUI/JSCanvasComponet/entry/build.gradle b/JSUI/JSCanvasComponet/entry/build.gradle index cccb71cae91018743841ab76aeb19c595f4ed847..68ec4e15705e1c4fd6ca07fe7ad0444a86546c7a 100644 --- a/JSUI/JSCanvasComponet/entry/build.gradle +++ b/JSUI/JSCanvasComponet/entry/build.gradle @@ -1,9 +1,9 @@ apply plugin: 'com.huawei.ohos.hap' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 defaultConfig { - compatibleSdkVersion 6 + compatibleSdkVersion 7 } buildTypes { release { @@ -14,7 +14,7 @@ ohos { } } - supportSystem "standard" + } dependencies { diff --git a/JSUI/JSCanvasComponet/figures/zh-cn_image_0000001237353117.gif b/JSUI/JSCanvasComponet/figures/zh-cn_image_0000001237353117.gif new file mode 100644 index 0000000000000000000000000000000000000000..893aace0e717a75d1f10dd6479c26de81c111bb4 Binary files /dev/null and b/JSUI/JSCanvasComponet/figures/zh-cn_image_0000001237353117.gif differ diff --git a/JSUI/JSCanvasComponet/figures/zh-cn_image_0000001238220835.png b/JSUI/JSCanvasComponet/figures/zh-cn_image_0000001238220835.png new file mode 100644 index 0000000000000000000000000000000000000000..dc81ebc7f00b5f88c0aec02f33f66fa41823cff5 Binary files /dev/null and b/JSUI/JSCanvasComponet/figures/zh-cn_image_0000001238220835.png differ diff --git "a/JSUI/JSCanvasComponet/figures/\345\217\226\347\211\210\346\234\254.png" "b/JSUI/JSCanvasComponet/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/JSUI/JSCanvasComponet/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/JSUI/JSCanvasComponet/figures/\346\210\252\345\233\276.png" "b/JSUI/JSCanvasComponet/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/JSUI/JSCanvasComponet/figures/\346\210\252\345\233\276.png" differ diff --git a/JSUI/JSCanvasComponet/public_sys-resources/icon-caution.gif b/JSUI/JSCanvasComponet/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/JSCanvasComponet/public_sys-resources/icon-caution.gif differ diff --git a/JSUI/JSCanvasComponet/public_sys-resources/icon-danger.gif b/JSUI/JSCanvasComponet/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/JSCanvasComponet/public_sys-resources/icon-danger.gif differ diff --git a/JSUI/JSCanvasComponet/public_sys-resources/icon-note.gif b/JSUI/JSCanvasComponet/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/JSUI/JSCanvasComponet/public_sys-resources/icon-note.gif differ diff --git a/JSUI/JSCanvasComponet/public_sys-resources/icon-notice.gif b/JSUI/JSCanvasComponet/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/JSUI/JSCanvasComponet/public_sys-resources/icon-notice.gif differ diff --git a/JSUI/JSCanvasComponet/public_sys-resources/icon-tip.gif b/JSUI/JSCanvasComponet/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/JSUI/JSCanvasComponet/public_sys-resources/icon-tip.gif differ diff --git a/JSUI/JSCanvasComponet/public_sys-resources/icon-warning.gif b/JSUI/JSCanvasComponet/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/JSCanvasComponet/public_sys-resources/icon-warning.gif differ diff --git a/JSUI/RatingApplication/README.md b/JSUI/RatingApplication/README.md index 5b97fd2e22c03ae1d42ff5331ad8931f4b993cb6..868c5b6d3e480b619e1913c7155c589985562a41 100644 --- a/JSUI/RatingApplication/README.md +++ b/JSUI/RatingApplication/README.md @@ -1,3 +1,190 @@ -# RatingApplication -简介 -• 此Demo使用JS UI中的rating组件,我们将会通过一个简单的样例,实现一个星级打分的效果 +# 1.介绍 + +- [应用场景](#section225718574575) + +OpenHarmony的ArkUI(基于JS扩展的类Web开发范式)提供了常用的接口和组件,开发者可以根据实际场景和开发需求,选用不同的组件和接口。本篇Codelab,我们将一起开启ArkUI(基于JS扩展的类Web开发范式)基础组件的学习之路。本教程是基础组件rating的使用。 + +在本教程中,我们将会通过一个简单的样例,实现一个星级打分的效果,开发者可以使用rating组件调节星级评分的大小。效果如下图所示,开发者还可以根据自己的需求添加不同的效果。 + +![](figures/unnaming.png)![](figures/unnaming-(1).png)![](figures/unnaming-(2).png) + +## 应用场景 + +- 购物、团购类应用打分评价场景。 + +# 2.相关概念 + +**[rating组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-rating.md):**评分条,表示用户使用感受的衡量标准条。 + +**[div组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-container-div.md)**:基础容器组件,用作页面结构的根节点或将内容进行分组。 + +**[text组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-text.md):**文本组件,用于呈现一段信息。 + +# 3.搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 4.将组件添加到布局文件中 + +在这个任务中,我们需要完成程序页面的新建和设计,并将程序使用到的rating组件添加到布局文件index.hml中。在完成新建项目后,我们看到系统自动创建了pages.index目录,在这个目录下,我们找到index.hml文件,开始进行页面设计。 + +打开index.hml文件,默认代码使用div组件和text组件来共同呈现文本显示的效果,具体代码如下: + +``` +
+ + {{ $t('strings.hello') }} {{ title }} + +
+``` + +## rating组件 + +开发者可以删除默认代码跟着接下来的步骤一起开发,整个布局文件使用div组件将页面进行划分,分别是上方的自定义星级打分和下方显示平均分星级。 + +``` +
+ 自定义星级打分 + + + + 平均分等级 + +
+``` + +rating组件的属性说明可参考下表: + + + + + + + + + + + + + + + + + + + + + + + +

名称

+

类型

+

默认值

+

描述

+

indicator

+

number

+

false

+

设置评分条是否作为一个指示器,此时用户不可操作。

+

stepsize

+

number

+

0.5

+

设置评分条的评星步长。

+

rating

+

number

+

0

+

设置评分条当前评星数。

+
+ +# 5.为页面设计样式 + +在这个任务中,我们将一起为写好的页面添加样式,上面所有的组件,我们都定义了class属性,对应的样式都定义在index.css中,有关css更多的知识可以参考[CSS语法参考](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-framework-syntax-css.md)。 + +## rating 组件样式 + +删掉默认代码后,在index.css中先添加如下代码: + +``` +/* 页面整体纵向布局 */ +.container { + flex-direction: column; +/* justify-content: center;*/ + align-items: center; + padding-top: 30px; + +} +/* 平均分等级样式 */ +.rate{ + width:200px; + height:45px; + margin-top: 20px; +} +/* 字体样式 */ +.avgText{ + text-align:center; + font-size:20px; + width: 200px; + color: #5A554D; + margin-top: 80px; + font-weight:900 +} +/*自定义星级布局 */ +.rateRed{ + star-background:url("/common/asserts/zdy1.png"); + star-foreground:url("/common/asserts/zdy2.png"); + star-secondary:url("/common/asserts/zdy3.png"); + width:200px; + height:45px; +} + +.rateBlue{ + star-background:url("/common/asserts/zdy1.png"); + star-foreground:url("/common/asserts/zdy2.png"); + star-secondary:url("/common/asserts/zdy3.png"); + width:200px; + height:45px; + margin-top: 10px; +} +.rateGreen{ + star-background:url("/common/asserts/zdy1.png"); + star-foreground:url("/common/asserts/zdy2.png"); + star-secondary:url("/common/asserts/zdy3.png"); + width:200px; + height:45px; +} +``` + +# 6.恭喜你 + +在本篇Codelab中,我们主要为大家讲解了如下JS基础组件 + +- rating + +通过一个代码示例,实现自定义星级打分以及显示星级平均分,从布局、样式、响应事件三个层面,逐步为大家进行代码讲解。希望通过本教程,各位开发者可以对以上基础组件具有更深刻的认识。 + +# 7.参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/JSUI/RatingApplication) \ No newline at end of file diff --git a/JSUI/RatingApplication/figures/unnaming-(1).png b/JSUI/RatingApplication/figures/unnaming-(1).png new file mode 100644 index 0000000000000000000000000000000000000000..4cecdd75496c600a7b922c570cb30f5b3004051f Binary files /dev/null and b/JSUI/RatingApplication/figures/unnaming-(1).png differ diff --git a/JSUI/RatingApplication/figures/unnaming-(2).png b/JSUI/RatingApplication/figures/unnaming-(2).png new file mode 100644 index 0000000000000000000000000000000000000000..9166ce76a950e0513779cb4608932acc5bad9bb3 Binary files /dev/null and b/JSUI/RatingApplication/figures/unnaming-(2).png differ diff --git a/JSUI/RatingApplication/figures/unnaming.png b/JSUI/RatingApplication/figures/unnaming.png new file mode 100644 index 0000000000000000000000000000000000000000..34327344c6ae4ab19f3c3226de3907fb8fe0215c Binary files /dev/null and b/JSUI/RatingApplication/figures/unnaming.png differ diff --git a/JSUI/RatingApplication/figures/zh-cn_image_0000001186628762.png b/JSUI/RatingApplication/figures/zh-cn_image_0000001186628762.png new file mode 100644 index 0000000000000000000000000000000000000000..ac82de23d348b0d2cd480533d0bfdb953fedba5f Binary files /dev/null and b/JSUI/RatingApplication/figures/zh-cn_image_0000001186628762.png differ diff --git a/JSUI/RatingApplication/figures/zh-cn_image_0000001186788670.png b/JSUI/RatingApplication/figures/zh-cn_image_0000001186788670.png new file mode 100644 index 0000000000000000000000000000000000000000..0d8ede8a42e6342c7fc6e7867f8e6c0e5235e8f1 Binary files /dev/null and b/JSUI/RatingApplication/figures/zh-cn_image_0000001186788670.png differ diff --git a/JSUI/RatingApplication/figures/zh-cn_image_0000001231948291.png b/JSUI/RatingApplication/figures/zh-cn_image_0000001231948291.png new file mode 100644 index 0000000000000000000000000000000000000000..a391afb524a0a2ed40453009569922e55e222a75 Binary files /dev/null and b/JSUI/RatingApplication/figures/zh-cn_image_0000001231948291.png differ diff --git a/JSUI/RatingApplication/figures/zh-cn_image_0000001232068355.png b/JSUI/RatingApplication/figures/zh-cn_image_0000001232068355.png new file mode 100644 index 0000000000000000000000000000000000000000..a6c4fa695ce057a78d148a103a90d39fb05cab16 Binary files /dev/null and b/JSUI/RatingApplication/figures/zh-cn_image_0000001232068355.png differ diff --git "a/JSUI/RatingApplication/figures/\345\217\226\347\211\210\346\234\254.png" "b/JSUI/RatingApplication/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/JSUI/RatingApplication/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/JSUI/RatingApplication/figures/\346\210\252\345\233\276.png" "b/JSUI/RatingApplication/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/JSUI/RatingApplication/figures/\346\210\252\345\233\276.png" differ diff --git a/JSUI/RatingApplication/public_sys-resources/icon-caution.gif b/JSUI/RatingApplication/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/RatingApplication/public_sys-resources/icon-caution.gif differ diff --git a/JSUI/RatingApplication/public_sys-resources/icon-danger.gif b/JSUI/RatingApplication/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/RatingApplication/public_sys-resources/icon-danger.gif differ diff --git a/JSUI/RatingApplication/public_sys-resources/icon-note.gif b/JSUI/RatingApplication/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/JSUI/RatingApplication/public_sys-resources/icon-note.gif differ diff --git a/JSUI/RatingApplication/public_sys-resources/icon-notice.gif b/JSUI/RatingApplication/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/JSUI/RatingApplication/public_sys-resources/icon-notice.gif differ diff --git a/JSUI/RatingApplication/public_sys-resources/icon-tip.gif b/JSUI/RatingApplication/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/JSUI/RatingApplication/public_sys-resources/icon-tip.gif differ diff --git a/JSUI/RatingApplication/public_sys-resources/icon-warning.gif b/JSUI/RatingApplication/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/RatingApplication/public_sys-resources/icon-warning.gif differ diff --git a/JSUI/ShoppingOpenHarmony/LICENSE b/JSUI/ShoppingOpenHarmony/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..7c357dc828cf7d8c783f10ed6bb1bac8a1e903c1 --- /dev/null +++ b/JSUI/ShoppingOpenHarmony/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2021 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/JSUI/ShoppingOpenHarmony/README.md b/JSUI/ShoppingOpenHarmony/README.md index f058162b4805336900d3d029c2fde205d330d66a..0c87de7c86c35ce304dd98e7e1f532deec4d78ea 100644 --- a/JSUI/ShoppingOpenHarmony/README.md +++ b/JSUI/ShoppingOpenHarmony/README.md @@ -1,11 +1,267 @@ -# ShoppingOpenHarmony +# 1 介绍 -ShoppingOpenHarmony +本篇Codelab我们最终会构建一个简易的购物应用。应用包含两级页面,分别是主页(商品浏览页签、购物车页签、我的页签)和商品详情页面。 -本篇Codelab是在HarmonyOS JS组件购物车应用的代码基础上,对OpenHarmony开发板进行的适配。 +两个页面都展示了丰富的JS UI组件,包括:自定义弹窗容器组件(dialog),列表组件(list),滑动容器组件(swiper),页签容器组件(tabs),按钮组件(button),图表组件(chart),分隔器组件(divider),图片组件(image),交互式组件(input),跑马灯组件(marquee),菜单组件(menu),滑动选择器组件(picker),进度条组件(progress),评分条组件(rating),搜索框组件(search)。 -我们将教会大家如何将一个HarmonyOS应用适配、部署到OpenHarmony开发板上。 +**最终效果预览如下图所示:** -案例最终效果如下图所示: +![](screenshots/device/zh-cn_image_0000001160725256.png) + +# 2 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +[获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制)。 + +搭建烧录环境。 + +1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + +2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +搭建开发环境: + +1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 +2. 开发环境配置完成后,请参考[使用工程工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + +3.工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + +- [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) +- [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) +- 工程示例: + +![](screenshots/device/截图.png) + + + +# 3 代码结构解读 + +本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在最后的参考中提供下载方式,接下来我们会用一小节来讲解整个工程的代码结构: + +![](screenshots/device/zh-cn_image_0000001206763755.png) + +- entry/src/main/js/default/common 文件夹存放一些公共的资源,比如图片。 +- entry/src/main/js/default/pages 文件夹存放页面布局,包含css、hml、js三类文件。 +- entry/src/main/config.json:配置文件。 + +# 4 构建主界面 + +主界面的效果图如下: + +![](screenshots/device/zh-cn_image_0000001236757413.png) + +点击应用的底部的不同图标,页面会随之切换,被选中的页面图片变红,图片示例和代码如下: + +![](screenshots/device/zh-cn_image_0000001192437236.png) ![](screenshots/device/zh-cn_image_0000001192117266.png) ![](screenshots/device/zh-cn_image_0000001236757247.png) + +``` +
+ + + + + + +
+``` + + + +# 5 构建商品列表页签 + +商品列表页签的效果图如下: + +![](screenshots/device/zh-cn_image_0000001237197743.png) + +可以看出商品类标页签由搜索栏和下面的商品列表组成。 + +1. 搜索框组件(search):用于提供用户搜索内容的输入区域,图片示例和代码如下: + + 页面展示: + + ![](screenshots/device/zh-cn_image_0000001237078267.png) + + ``` + + + ``` + +2. 商品列表,页签容器组件(tabs)实现: + + 的子组件(tab-bar):用来展示tab的标签区。 + + 的子组件(tab-content):用来展示tab的内容区。 + + ``` + + + {{ item }} + + + +
+ + +
+
+ + {{ $item.title }} + + + {{ $item.content }} + + + + ¥ + + + {{ $item.price }} + + +
+
+ + +
+
+
+
+
+
+
+ ``` + +3. 页面路由跳转:用户点击商品浏览页面的任意商品,页面会跳转到商品详情页面: + + ``` + detailPage() { + router.push({ + uri: 'pages/shoppingDetailsPage/shoppingDetailsPage' + }); + } + ``` + + + +# 6 构建购物车页签 + +购物车页面:用户将选中的商品加入购物车后,可以选中需要的商品进行结算,图片示例和代码如下: + +![](screenshots/device/zh-cn_image_0000001237197221.png) + +``` +
+
+
+ + + + +
+ + {{ $item.title }} + + + + {{ $item.price }} + + + 元 + + +
+
+ + +
+
+``` + +# 7 构建“我的”页签 + +1. “我的”页面布局,图片示例和代码如下: + + ![](screenshots/device/zh-cn_image_0000001237197311.png) + + ``` +
+ + {{ pageWord.myDeals }} + +
+
+ + + + {{ $item.title }}{{ $item.num }} + +
+
+
+ ``` + +# 8 构建商品详情页面 + +1. 滑动容器(swiper):用户可以在swiper组件上进行滑动 左右切换图片,或者3s自动滑动一次,图片示例和代码如下: + + ![](screenshots/device/zh-cn_image_0000001236917309.png) + + ``` + +
+ + +
+
+ ``` + +2. 对样式进行动态双向绑定,可以修改“次日达”字体的颜色 ,图片示例和代码如下: + + ![](screenshots/device/zh-cn_image_0000001191957374.png) ![](screenshots/device/zh-cn_image_0000001192277310.png) ![](screenshots/device/zh-cn_image_0000001192437304.png) ![](screenshots/device/zh-cn_image_0000001192117334.png) + + ``` + {{pageInfo.nextDayReach}} + + export default { + data: { + textColor: '#FF3536', + } + } + ``` + +3. 点击详情页右上角的图标会展示menu菜单,图片示例和代码如下: + + ![](screenshots/device/zh-cn_image_0000001193059680.png) + + ``` + + ``` + +4. 点击menu菜单的“浏览量”,跳转到浏览量页面:chart组件(曲线图可以实时动态更新数据),图片示例和代码如下: + + ![](screenshots/device/zh-cn_image_0000001192090980.png) + + ``` + + ``` + +5. 点击立即抢购会弹出一个含有进度条(progress)的弹框 ,图片示例和代码如下: + + ![](screenshots/device/zh-cn_image_0000001192117336.png) + + ``` + + ``` + + + +# 9 恭喜你 + +目前你已经成功完成了Codelab并且学到了: + +- 如何使用OpenHarmony ArkUI常用组件。 +- 如何实现各页面之间的跳转。 -![](screenshots/device/ShoppingDemo.PNG) \ No newline at end of file diff --git a/JSUI/ShoppingOpenHarmony/RELEASE-NOTES.MD b/JSUI/ShoppingOpenHarmony/RELEASE-NOTES.MD new file mode 100644 index 0000000000000000000000000000000000000000..9087a1482627f316280b762b6c5adc73c0d438d1 --- /dev/null +++ b/JSUI/ShoppingOpenHarmony/RELEASE-NOTES.MD @@ -0,0 +1 @@ +1.0.0.1 Initial version \ No newline at end of file diff --git a/JSUI/ShoppingOpenHarmony/build.gradle b/JSUI/ShoppingOpenHarmony/build.gradle index fa230b707f071d544736902167fda519b343d087..e8ae8529c202bf288060523968ece50d9bb2fc26 100644 --- a/JSUI/ShoppingOpenHarmony/build.gradle +++ b/JSUI/ShoppingOpenHarmony/build.gradle @@ -3,31 +3,32 @@ apply plugin: 'com.huawei.ohos.app' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 + supportSystem "standard" } - + buildscript { repositories { maven { - url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/' + url 'https://repo.huaweicloud.com/repository/maven/' } maven { - url 'http://mirrors.tools.huawei.com/maven/' + url 'https://developer.huawei.com/repo/' } } dependencies { - classpath 'com.huawei.ohos:hap:3.0.1.5' - classpath 'com.huawei.ohos:decctest:3.0.1.1' + classpath 'com.huawei.ohos:hap:3.0.3.4' + classpath 'com.huawei.ohos:decctest:1.2.6.0' } } allprojects { repositories { maven { - url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/' + url 'https://repo.huaweicloud.com/repository/maven/' } maven { - url 'http://mirrors.tools.huawei.com/maven/' + url 'https://developer.huawei.com/repo/' } } -} +} \ No newline at end of file diff --git a/JSUI/ShoppingOpenHarmony/entry/build.gradle b/JSUI/ShoppingOpenHarmony/entry/build.gradle index 6c2dca308825d3d38937c45c03918e1628bbfb75..17ca3eda109099e73948aaff67295f61729ecb22 100644 --- a/JSUI/ShoppingOpenHarmony/entry/build.gradle +++ b/JSUI/ShoppingOpenHarmony/entry/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'com.huawei.ohos.hap' ohos { compileSdkVersion 6 defaultConfig { - compatibleSdkVersion 6 + compatibleSdkVersion 7 } buildTypes { release { @@ -13,11 +13,9 @@ ohos { } } } - - supportSystem "standard" } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) - testImplementation 'junit:junit:4.13' -} + testImplementation 'junit:junit:4.13.1' +} \ No newline at end of file diff --git a/JSUI/ShoppingOpenHarmony/entry/src/main/config.json b/JSUI/ShoppingOpenHarmony/entry/src/main/config.json index 0e2472a094b872f4b6429fafd174e12977584236..de9e19374c298b83933f7659b079ef705b654110 100644 --- a/JSUI/ShoppingOpenHarmony/entry/src/main/config.json +++ b/JSUI/ShoppingOpenHarmony/entry/src/main/config.json @@ -35,7 +35,9 @@ ], "orientation": "unspecified", "visible": true, + "srcPath": "default", "name": "com.huawei.shopping.MainAbility", + "srcLanguage": "js", "icon": "$media:icon", "description": "$string:mainability_description", "formsEnabled": false, diff --git a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/app.js b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/app.js index 6d060ffe5682c19fc83e2274a9e62cbc40a655f8..e6fa5981b585a8e16252865003bbaed50eb0bd35 100644 --- a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/app.js +++ b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/app.js @@ -1,8 +1,21 @@ +/* + * Copyright (c) 2021 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 default { - onCreate() { - console.info("Application onCreate"); - }, - onDestroy() { - console.info("Application onDestroy"); - } + onCreate() { + }, + onDestroy() { + } }; diff --git a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.css b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.css index c09c28e2c538ccad98671068ebf6f4cf35903fc7..1c00b34380a45a81dea75174fb1cbba79d9dae96 100644 --- a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.css +++ b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.css @@ -35,7 +35,7 @@ margin-bottom: 65px; } -.tabcontent { +.tab-content { width: 100%; height: 85%; justify-content: center; @@ -68,7 +68,7 @@ color: red; } -.todo-wraper { +.todo-wrapper { width: 100%; height: 100%; } @@ -265,13 +265,13 @@ font-size: 24px; } -.container-my-top-divss { +.container-my-top-div2 { position: absolute; top: 50px; right: 45px; } -.container-my-top-divss-image { +.container-my-top-div2-image { width: 22px; height: 22px; } diff --git a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.hml b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.hml index 0022b5d2b56fcb7c09bc667713433d507f48ad6d..002105882556bcb36b100a8b42e6831da81e32de 100644 --- a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.hml +++ b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.hml @@ -20,12 +20,12 @@ - {{ item }} + {{ item }} - +
- +
@@ -56,12 +56,12 @@
- +
- {{ pageWord.shopingCart }} + {{ pageWord.shoppingCart }}
@@ -125,8 +125,8 @@ {{ pageWord.memberName }}{{ pageWord.nickname }}
-
- +
+
diff --git a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.js b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.js index ce21b57b79fca3b31fd745f76830c3724b2f8e95..d6921f14a44a8403efbf24875014b20c349aee30 100644 --- a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.js +++ b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/homepage/homepage.js @@ -17,509 +17,509 @@ import router from '@system.router'; import prompt from '@system.prompt'; export default { - data: { - pageWord: { - searchKeyWord: '寻找宝贝、店铺', - searchValue: '手机', - shopingCart: '购物车', - settlement: '结算', - nickname: '小明同学', - memberName: '会员名:', - myDeals: '我的交易', - more: '更多' - }, - priceTotal: 0, - flag: 1, - zeroFlag: 0, - oneFlag: 1, - twoFlag: 2, - threeFlag: 3, - fourFlag: 4, - titileList: ['热销单品', '精品推荐', '智慧生活', '年货节'], - contentList: ['First', 'Second', 'Third', 'Four'], - latestList: [], - hotList: [ - { - title: 'HUAWEI nova 8 Pro ', - content: '10:08限时开售', - price: '3999', - imgSrc: "/common/picture/HW (1).png" - }, { - title: 'HUAWEI Mate 30E Pro 5G', - content: '享3期免息 ', - price: '5299', - imgSrc: "/common/picture/HW (2).png" - }, { - title: 'HUAWEI MatePad Pro', - content: '旗舰甄选 ', - price: '3799', - imgSrc: "/common/picture/HW (3).png" - }, { - title: '华为畅享20 SE', - content: '新品上市 ', - price: '1499', - imgSrc: "/common/picture/HW (4).png" - }, { - title: 'HUAWEI WATCH FIT', - content: '智能生活助手', - price: '769', - imgSrc: "/common/picture/HW (5).png" - } - ], - fineProductList: [ - { - title: 'HUAWEI MateBook X Pro 2021款', - content: '商务轻薄笔记本 ', - price: '9999', - imgSrc: "/common/picture/HW (6).png" - }, { - title: 'HUAWEI Mate 30 RS 保时捷设计', - content: '致敬时代 ', - price: '12999', - imgSrc: "/common/picture/HW (7).png" - }, { - title: '华为智慧屏 55英寸', - content: '享3期免息', - price: '4299', - imgSrc: "/common/picture/HW (8).png" - }, { - title: '华为畅享20 Pro', - content: '购机赠耳机 ', - price: '1999', - imgSrc: "/common/picture/HW (9).png" - }, { - title: '华为智能体脂秤 3', - content: '享3期免息', - price: '169', - imgSrc: "/common/picture/HW (10).png" - } - ], - wisdomList: [ - { - title: 'HUAWEI P40 Pro+ 5G', - content: '限量赠保护壳 ', - price: '7988', - imgSrc: "/common/picture/HW (11).png" - }, { - title: 'HUAWEI FreeBuds Pro', - content: '享3期免息', - price: '1099', - imgSrc: "/common/picture/HW (12).png" - }, { - title: 'HUAWEI MateBook X', - content: '享3期免息 ', - price: '8999', - imgSrc: "/common/picture/HW (13).png" - }, { - title: '红帕智能降温杯', - content: '智能喝水提醒 ', - price: '179', - imgSrc: "/common/picture/HW (14).png" - }, { - title: 'YESOUL野小兽智能动感单车S1', - content: '静音不扰邻 ', - price: '1299', - imgSrc: "/common/picture/HW (15).png" - }], - allList: [], - icon: { - buys: "/common/nav/icon-buy.png", - buy: "/common/nav/icon-buy.png", - home: '/common/nav/icon-home.png', - messages: '/common/nav/icon-message.png', - message: '/common/nav/icon-message.png', - messageSelect: '/common/nav/icon-message-select.png', - shoppingCarts: '/common/nav/icon-shopping-cart.png', - shoppingCart: '/common/nav/icon-shopping-cart.png', - shoppingCartSelect: '/common/nav/icon-shopping-cart-select.png', - mys: '/common/nav/iocn-my.png', - my: '/common/nav/iocn-my.png', - mySelect: '/common/nav/icon-my-select.png', - }, - iconImageFlag: 1, - menu: [ - { - id: '01', - title: '收藏', - num: '10' - }, - { - id: '02', - title: '历史浏览', - num: '1000' - }, - { - id: '03', - title: '关注', - num: '10' - }, - { - id: '04', - title: '粉丝', - num: '10000' - } - ], - transaction: [ - { - id: '01', - title: '我发布的', - num: '520', - src: '/common/nav/icon-menu-release.png' - }, - { - id: '02', - title: '我卖出的', - num: '520', - src: '/common/nav/icon-menu-sell.png' - }, - { - id: '03', - title: '我买到的', - num: '10', - src: '/common/nav/icon-menu-buy.png' - } - ], - more1: [ - { - id: '01', - title: '发布规范', - num: '520', - src: '/common/nav/icon-menu-release.png' - }, - { - id: '02', - title: '创作中心', - num: '520', - src: '/common/nav/icon-menu-sell.png' - }, - { - id: '03', - title: '我的帖子', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '04', - title: '我的游戏', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '05', - title: '我租到的', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '06', - title: '我的拍卖', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '07', - title: '我的兼职', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '08', - title: '我的租房', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '09', - title: '实名认证', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '10', - title: '我的红包', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '11', - title: '客服中心', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '12', - title: '招商认证', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '13', - title: '天天拍卖', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '14', - title: '我的设置', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '15', - title: '关于', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, { - id: '16', - title: '作品认证', - num: '10', - src: '/common/nav/icon-menu-buy.png' - } - ], - more: [ - [ - { - id: '01', - title: '发布规范', - num: '520', - src: '/common/nav/icon-menu-release.png' - }, - { - id: '02', - title: '创作中心', - num: '520', - src: '/common/nav/icon-menu-sell.png' - }, - { - id: '03', - title: '我的帖子', - num: '10', - src: '/common/nav/icon-menu-buy.png' - } - ], - [ - { - id: '04', - title: '我的游戏', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '05', - title: '我租到的', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '06', - title: '我的拍卖', - num: '10', - src: '/common/nav/icon-menu-buy.png' - } - ], - [ - { - id: '07', - title: '我的兼职', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '08', - title: '我的租房', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '09', - title: '实名认证', - num: '10', - src: '/common/nav/icon-menu-buy.png' - } - ], - [ - { - id: '10', - title: '我的红包', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '11', - title: '客服中心', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '12', - title: '招商认证', - num: '10', - src: '/common/nav/icon-menu-buy.png' - } - ], - [ - { - id: '13', - title: '天天拍卖', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '14', - title: '我的设置', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '15', - title: '关于软件', - num: '10', - src: '/common/nav/icon-menu-buy.png' - } - ], - [ - { - id: '16', - title: '作品认证', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '17', - title: '天天拍卖', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '18', - title: '我的设置', - num: '10', - src: '/common/nav/icon-menu-buy.png' - } - ], - [ - { - id: '19', - title: '关于软件', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, { - id: '20', - title: '作品认证', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '21', - title: '天天拍卖', - num: '10', - src: '/common/nav/icon-menu-buy.png' - } - ], - [ - { - id: '22', - title: '我的设置', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, - { - id: '23', - title: '关于软件', - num: '10', - src: '/common/nav/icon-menu-buy.png' - }, { - id: '24', - title: '作品认证', - num: '10', - src: '/common/nav/icon-menu-buy.png' - } - ] - ], + data: { + pageWord: { + searchKeyWord: '寻找宝贝、店铺', + searchValue: '手机', + shoppingCart: '购物车', + settlement: '结算', + nickname: '小明同学', + memberName: '会员名:', + myDeals: '我的交易', + more: '更多' }, - clickAction() { - router.replace({ - uri: 'pages/index/index', - params: {} - }); + priceTotal: 0, + flag: 1, + zeroFlag: 0, + oneFlag: 1, + twoFlag: 2, + threeFlag: 3, + fourFlag: 4, + titleList: ['热销单品', '精品推荐', '智慧生活', '年货节'], + contentList: ['First', 'Second', 'Third', 'Four'], + latestList: [], + hotList: [ + { + title: 'HUAWEI nova 8 Pro ', + content: '10:08限时开售', + price: '3999', + imgSrc: '/common/picture/HW (1).png' + }, { + title: 'HUAWEI Mate 30E Pro 5G', + content: '享3期免息 ', + price: '5299', + imgSrc: '/common/picture/HW (2).png' + }, { + title: 'HUAWEI MatePad Pro', + content: '旗舰甄选 ', + price: '3799', + imgSrc: '/common/picture/HW (3).png' + }, { + title: '华为畅享20 SE', + content: '新品上市 ', + price: '1499', + imgSrc: '/common/picture/HW (4).png' + }, { + title: 'HUAWEI WATCH FIT', + content: '智能生活助手', + price: '769', + imgSrc: '/common/picture/HW (5).png' + } + ], + fineProductList: [ + { + title: 'HUAWEI MateBook X Pro 2021款', + content: '商务轻薄笔记本 ', + price: '9999', + imgSrc: '/common/picture/HW (6).png' + }, { + title: 'HUAWEI Mate 30 RS 保时捷设计', + content: '致敬时代 ', + price: '12999', + imgSrc: '/common/picture/HW (7).png' + }, { + title: '华为智慧屏 55英寸', + content: '享3期免息', + price: '4299', + imgSrc: '/common/picture/HW (8).png' + }, { + title: '华为畅享20 Pro', + content: '购机赠耳机 ', + price: '1999', + imgSrc: '/common/picture/HW (9).png' + }, { + title: '华为智能体脂秤 3', + content: '享3期免息', + price: '169', + imgSrc: '/common/picture/HW (10).png' + } + ], + wisdomList: [ + { + title: 'HUAWEI P40 Pro+ 5G', + content: '限量赠保护壳 ', + price: '7988', + imgSrc: '/common/picture/HW (11).png' + }, { + title: 'HUAWEI FreeBuds Pro', + content: '享3期免息', + price: '1099', + imgSrc: '/common/picture/HW (12).png' + }, { + title: 'HUAWEI MateBook X', + content: '享3期免息 ', + price: '8999', + imgSrc: '/common/picture/HW (13).png' + }, { + title: '红帕智能降温杯', + content: '智能喝水提醒 ', + price: '179', + imgSrc: '/common/picture/HW (14).png' + }, { + title: 'YESOUL野小兽智能动感单车S1', + content: '静音不扰邻 ', + price: '1299', + imgSrc: '/common/picture/HW (15).png' + }], + allList: [], + icon: { + buys: '/common/nav/icon-buy.png', + buy: '/common/nav/icon-buy.png', + home: '/common/nav/icon-home.png', + messages: '/common/nav/icon-message.png', + message: '/common/nav/icon-message.png', + messageSelect: '/common/nav/icon-message-select.png', + shoppingCarts: '/common/nav/icon-shopping-cart.png', + shoppingCart: '/common/nav/icon-shopping-cart.png', + shoppingCartSelect: '/common/nav/icon-shopping-cart-select.png', + mys: '/common/nav/icon-my.png', + my: '/common/nav/icon-my.png', + mySelect: '/common/nav/icon-my-select.png' }, - change(e) { - this.allList = []; - if (e.index === this.zeroFlag) { - this.allList = [...this.hotList, ...this.fineProductList, ...this.wisdomList]; - } else if (e.index === this.oneFlag) { - this.allList = this.hotList; - } else if (e.index === this.twoFlag) { - this.allList = this.fineProductList; - } else if (e.index === this.threeFlag) { - this.allList = this.wisdomList; + iconImageFlag: 1, + menu: [ + { + id: '01', + title: '收藏', + num: '10' + }, + { + id: '02', + title: '历史浏览', + num: '1000' + }, + { + id: '03', + title: '关注', + num: '10' + }, + { + id: '04', + title: '粉丝', + num: '10000' + } + ], + transaction: [ + { + id: '01', + title: '我发布的', + num: '520', + src: '/common/nav/icon-menu-release.png' + }, + { + id: '02', + title: '我卖出的', + num: '520', + src: '/common/nav/icon-menu-sell.png' + }, + { + id: '03', + title: '我买到的', + num: '10', + src: '/common/nav/icon-menu-buy.png' + } + ], + more1: [ + { + id: '01', + title: '发布规范', + num: '520', + src: '/common/nav/icon-menu-release.png' + }, + { + id: '02', + title: '创作中心', + num: '520', + src: '/common/nav/icon-menu-sell.png' + }, + { + id: '03', + title: '我的帖子', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '04', + title: '我的游戏', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '05', + title: '我租到的', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '06', + title: '我的拍卖', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '07', + title: '我的兼职', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '08', + title: '我的租房', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '09', + title: '实名认证', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '10', + title: '我的红包', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '11', + title: '客服中心', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '12', + title: '招商认证', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '13', + title: '天天拍卖', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '14', + title: '我的设置', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '15', + title: '关于', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, { + id: '16', + title: '作品认证', + num: '10', + src: '/common/nav/icon-menu-buy.png' + } + ], + more: [ + [ + { + id: '01', + title: '发布规范', + num: '520', + src: '/common/nav/icon-menu-release.png' + }, + { + id: '02', + title: '创作中心', + num: '520', + src: '/common/nav/icon-menu-sell.png' + }, + { + id: '03', + title: '我的帖子', + num: '10', + src: '/common/nav/icon-menu-buy.png' } - }, - onInit() { - this.latestList = [...this.hotList, ...this.fineProductList, ...this.wisdomList] - this.allList = [...this.hotList, ...this.fineProductList, ...this.wisdomList] - }, - submitColumn(e) { - prompt.showToast({ - message: e.text + ' 正在搜索中...' - }); - }, - detailPage() { - router.push({ - uri: "pages/shoppingDetailsPage/shoppingDetailsPage" - }); - }, - stickFloat() { - }, - clickBuy() { - this.iconImageFlag = this.oneFlag; - this.flag = this.oneFlag; - this.ifFlag(); - }, - clickShoppingCart() { - this.iconImageFlag = this.threeFlag; - this.flag = this.threeFlag; - this.priceTotal = parseInt(this.zeroFlag); - this.ifFlag(); - }, - clickMy() { - this.iconImageFlag = this.fourFlag; - this.flag = this.fourFlag; - this.ifFlag(); - }, - ifFlag() { - if (this.iconImageFlag === this.oneFlag) { - this.icon.buys = this.icon.buy; - this.icon.messages = this.icon.message; - this.icon.shoppingCarts = this.icon.shoppingCart; - this.icon.mys = this.icon.my; - } else if (this.iconImageFlag === this.twoFlag) { - this.icon.buys = this.icon.home; - this.icon.messages = this.icon.messageSelect; - this.icon.shoppingCarts = this.icon.shoppingCart; - this.icon.mys = this.icon.my; - } else if (this.iconImageFlag === this.threeFlag) { - this.icon.buys = this.icon.home; - this.icon.messages = this.icon.message; - this.icon.shoppingCarts = this.icon.shoppingCartSelect; - this.icon.mys = this.icon.my; - } else if (this.iconImageFlag === this.fourFlag) { - this.icon.buys = this.icon.home; - this.icon.messages = this.icon.message; - this.icon.shoppingCarts = this.icon.shoppingCart; - this.icon.mys = this.icon.mySelect; + ], + [ + { + id: '04', + title: '我的游戏', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '05', + title: '我租到的', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '06', + title: '我的拍卖', + num: '10', + src: '/common/nav/icon-menu-buy.png' } - }, - addShopping(e) { - if (e.checked) { - this.priceTotal += parseInt(e.target.attr.value); - } else { - this.priceTotal -= parseInt(e.target.attr.value); + ], + [ + { + id: '07', + title: '我的兼职', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '08', + title: '我的租房', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '09', + title: '实名认证', + num: '10', + src: '/common/nav/icon-menu-buy.png' } - }, - clickSettlement() { - prompt.showToast({ - message: "正在结算......" - }); + ], + [ + { + id: '10', + title: '我的红包', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '11', + title: '客服中心', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '12', + title: '招商认证', + num: '10', + src: '/common/nav/icon-menu-buy.png' + } + ], + [ + { + id: '13', + title: '天天拍卖', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '14', + title: '我的设置', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '15', + title: '关于软件', + num: '10', + src: '/common/nav/icon-menu-buy.png' + } + ], + [ + { + id: '16', + title: '作品认证', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '17', + title: '天天拍卖', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '18', + title: '我的设置', + num: '10', + src: '/common/nav/icon-menu-buy.png' + } + ], + [ + { + id: '19', + title: '关于软件', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, { + id: '20', + title: '作品认证', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '21', + title: '天天拍卖', + num: '10', + src: '/common/nav/icon-menu-buy.png' + } + ], + [ + { + id: '22', + title: '我的设置', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, + { + id: '23', + title: '关于软件', + num: '10', + src: '/common/nav/icon-menu-buy.png' + }, { + id: '24', + title: '作品认证', + num: '10', + src: '/common/nav/icon-menu-buy.png' + } + ] + ] + }, + clickAction() { + router.replace({ + uri: 'pages/index/index', + params: {} + }); + }, + change(e) { + this.allList = []; + if (e.index === this.zeroFlag) { + this.allList = [...this.hotList, ...this.fineProductList, ...this.wisdomList]; + } else if (e.index === this.oneFlag) { + this.allList = this.hotList; + } else if (e.index === this.twoFlag) { + this.allList = this.fineProductList; + } else if (e.index === this.threeFlag) { + this.allList = this.wisdomList; + } + }, + onInit() { + this.latestList = [...this.hotList, ...this.fineProductList, ...this.wisdomList]; + this.allList = [...this.hotList, ...this.fineProductList, ...this.wisdomList]; + }, + submitColumn(e) { + prompt.showToast({ + message: e.text + ' 正在搜索中...' + }); + }, + detailPage() { + router.push({ + uri: 'pages/shoppingDetailsPage/shoppingDetailsPage' + }); + }, + stickFloat() { + }, + clickBuy() { + this.iconImageFlag = this.oneFlag; + this.flag = this.oneFlag; + this.ifFlag(); + }, + clickShoppingCart() { + this.iconImageFlag = this.threeFlag; + this.flag = this.threeFlag; + this.priceTotal = parseInt(this.zeroFlag); + this.ifFlag(); + }, + clickMy() { + this.iconImageFlag = this.fourFlag; + this.flag = this.fourFlag; + this.ifFlag(); + }, + ifFlag() { + if (this.iconImageFlag === this.oneFlag) { + this.icon.buys = this.icon.buy; + this.icon.messages = this.icon.message; + this.icon.shoppingCarts = this.icon.shoppingCart; + this.icon.mys = this.icon.my; + } else if (this.iconImageFlag === this.twoFlag) { + this.icon.buys = this.icon.home; + this.icon.messages = this.icon.messageSelect; + this.icon.shoppingCarts = this.icon.shoppingCart; + this.icon.mys = this.icon.my; + } else if (this.iconImageFlag === this.threeFlag) { + this.icon.buys = this.icon.home; + this.icon.messages = this.icon.message; + this.icon.shoppingCarts = this.icon.shoppingCartSelect; + this.icon.mys = this.icon.my; + } else if (this.iconImageFlag === this.fourFlag) { + this.icon.buys = this.icon.home; + this.icon.messages = this.icon.message; + this.icon.shoppingCarts = this.icon.shoppingCart; + this.icon.mys = this.icon.mySelect; + } + }, + addShopping(e) { + if (e.checked) { + this.priceTotal += parseInt(e.target.attr.value); + } else { + this.priceTotal -= parseInt(e.target.attr.value); } -} \ No newline at end of file + }, + clickSettlement() { + prompt.showToast({ + message: '正在结算......' + }); + } +}; diff --git a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.css b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.css index 138a60978da5994fe05c77294438694000dc101c..a1b2ad374a5328aa5cffe0667a97f3ed74dc8c77 100644 --- a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.css +++ b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.css @@ -127,8 +127,8 @@ } .icon-style { - width: 30px; - height: 30px; + width: 60px; + height: 60px; } .content-annualPrice-div { @@ -208,7 +208,10 @@ } .container-top-div { - height: 65px; + padding-top: 10px; + padding-left: 20px; + padding-right: 20px; + height: 90px; background-color: skyblue; position: fixed; top: 0px; @@ -268,7 +271,7 @@ font-size: 30px; } -.dialog-div-titleimage { +.dialog-div-title-image { width: 320px; height: 320px; } @@ -362,7 +365,7 @@ margin: 0px 10px; } -.pinn { +.to-top { width: 80px; height: 80px; position: fixed; diff --git a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.hml b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.hml index 76e983c16ad640469eee2e86fefd11a4e1124964..079ac71f424fed1554eaec9f98ddd1277a307dc3 100644 --- a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.hml +++ b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.hml @@ -16,8 +16,8 @@
-
- +
+
@@ -26,16 +26,16 @@
- +
@@ -58,40 +58,40 @@ - {{pageInfo.annualPrice}} + {{ pageInfo.annualPrice }}
- {{pageInfo.productTitle}} + {{ pageInfo.productTitle }} - {{pageInfo.productIntroduction}} + {{ pageInfo.productIntroduction }}
- {{pageInfo.marqueeCustomData}} + {{ pageInfo.marqueeCustomData }}
- {{pageInfo.shipment}} + {{ pageInfo.shipment }} - - {{pageInfo.nextDayReach}} + + {{ pageInfo.nextDayReach }}
- {{pageInfo.select}} + {{ pageInfo.select }} - {{selectCityString}} + {{ selectCityString }}
@@ -100,10 +100,10 @@
- {{pageInfo.guarantee}} + {{ pageInfo.guarantee }} - {{pageInfo.guaranteeContent}} + {{ pageInfo.guaranteeContent }}
@@ -112,43 +112,43 @@
- - {{$item.title}} + + {{ $item.title }} - {{$item.content}} + {{ $item.content }}
- +
- {{pageInfo.nowSell}} + {{ pageInfo.nowSell }}
- +
- +
- +
- {{pageInfo.annualPrice}} + {{ pageInfo.annualPrice }} - {{pageInfo.inventory}} + {{ pageInfo.inventory }}
@@ -157,7 +157,7 @@
- {{pageInfo.selectRewardTime}} + {{ pageInfo.selectRewardTime }}
- {{pageInfo.selectRewardCity}} + {{ pageInfo.selectRewardCity }}
- +
- {{pageInfo.nowSell}} + {{ pageInfo.nowSell }}
- +
- + - {{pageInfo.saleFlash}}( + {{ pageInfo.saleFlash }}( - {{progress.percent}}%) + {{ progress.percent }}%) - {{pageInfo.justMoment}} + {{ pageInfo.justMoment }}
- +
- {{pageInfo.softwareScore}} + {{ pageInfo.softwareScore }}
- +
- {{pageInfo.ratingReason}} + {{ pageInfo.ratingReason }} -
- {{pageInfo.confirm}} + {{ pageInfo.confirm }} - - {{pageInfo.cancel}} + + {{ pageInfo.cancel }}
diff --git a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.js b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.js index bb7a09947513d24455651f223663d7edd7718fcb..ad577d4b225127712b94367f12dadf07a3139aa4 100644 --- a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.js +++ b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/shoppingDetailsPage/shoppingDetailsPage.js @@ -18,229 +18,231 @@ import prompt from '@system.prompt'; import app from '@system.app'; export default { - data: { - pageInfo: { - scoring: '评分', - sharing: '分享', - views: '浏览量', - exit: '退出', - annualPrice: '年货节 ¥9999', - productTitle: '【新品】HUAWEI MateBook X Pro 2021款', - productIntroduction: '13.9英寸全新11代酷睿i7 16G 512G 商务轻薄笔记本 3K触控全面屏 锐炬显卡 多屏协同 翡冷翠', - marqueeCustomData: '此商品活动中,请尽快购买!', - shipment: '发货', - nextDayReach: '次日达', - select: '选择', - rewardTo: '配送至:', - guarantee: '保障', - guaranteeContent: '假一赔一 - 满66包邮', - nowSell: '立即抢购', - inventory: '库存999件', - selectRewardTime: '选择配送时间:', - selectRewardCity: '选择配送城市:', - saleFlash: '抢购中', - justMoment: '请稍等......', - softwareScore: '软件评分', - ratingReason: '评分理由', - confirm: '确认', - cancel: '取消', - ratingPlaceholder: '请输入评分理由(非必填)', - }, - clearFlag: -1, - zeroFlag: 0, - oneFlag: 1, - twoFlag: 2, - threeFlag: 3, - fourFlag: 4, - textColor: '#FF3536', - flagNum: 0, - ratingReason: '', - ratingNum: 0, - scrollAmount: 10, - loop: '-1', - marqueeDir: 'right', - interval: null, - progress: { - percent: 0, - secondarypercent: 0, - }, - swiperList: [1, 2, 3, 4, 5, 6, 7, 8], - swiperLists: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], - newDate: JSON.stringify(new Date()).substring(1,11), - cityList: [['中国'], ['湖北省'], ['武汉市', '黄石市', '十堰市', '宜昌市', '襄阳市', '鄂州市', '荆门市', '孝感市', '荆州市', '黄冈市', '咸宁市', '随州市', '恩施', '仙桃市', '潜江市', '天门市', '神农架林区']], - selectCityList: [['中国'], ['湖北省'], ['武汉市']], - selectCityString: '', - contentList: [ - { - title: '屏幕尺寸', - content: '13.9英寸', - }, { - title: '运行内存', - content: '16GB', - }, { - title: '传播名', - content: 'HUAWEI MateBook X Pro', - }, { - title: '屏幕色彩', - content: '100% sRGB(典型值)', - }, { - title: '电池容量', - content: '56Wh(额定容量)', - }, { - title: '存储容量', - content: '512GB', - }, { - title: '分辨率', - content: '3000x2000', - }, { - title: 'CPU型号', - content: '第11代英特尔® 酷睿™ i5-1135G7 处理器', - }, { - title: 'CPU核数', - content: '4核', - }, { - title: '上市时间', - content: '2021年1月', - } - ] - }, - onInit() { - }, - onShow() { - this.selectCityString = this.selectCityList.join('-'); - }, - selectCity() { - this.$element('simpledialog').show(); - prompt.showToast({ - message: '选择' - }); - }, - selectSafeguard() { - prompt.showToast({ - message: '保障' - }); - }, - cancelSchedule() { - this.$element('simpledialog').close(); - prompt.showToast({ - message: 'close dialog' - }); - }, - backPage() { - router.push({ - uri: "pages/homepage/homepage" - }); - }, - buy() { - const PROGRESSQUARTERS = 25; - const PROGRESSONEHALF = 50; - const PROGRESSTHREEQUARTERS = 75; - const PROGRESSONEPERCENT = 100; - if (this.flagNum === 0) { - this.textColor = '#27FF50'; - } else if (this.flagNum === this.oneFlag) { - this.textColor = '#A774FF'; - } else if (this.flagNum === this.twoFlag) { - this.textColor = '#FFF244'; - } else { - this.flagNum = this.clearFlag; - this.textColor = '#291CFF'; - } - this.flagNum += this.oneFlag; - this.$element('simpledialogs').show(); - let interval = setInterval(() => { - if ((this.progress.secondarypercent === PROGRESSQUARTERS || this.progress.secondarypercent === PROGRESSONEHALF || this.progress.secondarypercent === PROGRESSTHREEQUARTERS) && this.progress.percent !== PROGRESSONEPERCENT) { - this.progress.percent += this.oneFlag; - this.progress.secondarypercent += this.oneFlag; - } else if (this.progress.secondarypercent === PROGRESSONEPERCENT && this.progress.percent !== PROGRESSONEPERCENT) { - this.progress.percent += this.oneFlag; - this.progress.secondarypercent = this.zeroFlag; - } else if (this.progress.secondarypercent !== PROGRESSONEPERCENT) { - this.progress.secondarypercent += this.oneFlag; - } else if (this.progress.percent === PROGRESSONEPERCENT && this.progress.secondarypercent === PROGRESSONEPERCENT) { - this.$element('simpledialog').close(); - prompt.showToast({ - message: '抢购成功......' - }); - clearInterval(interval); - } else { - prompt.showToast({ - message: '正在处理中......' - }); - } - this.interval = interval; - },30); - }, - cancelBuyDialog() { - const PROGRESSONEPERCENT = 100; - if (this.progress.secondarypercent === PROGRESSONEPERCENT && this.progress.percent === PROGRESSONEPERCENT) { - prompt.showToast({ - message: '抢购成功......' - }); - } - this.$element('simpledialog').close(); - this.progress.secondarypercent = this.zeroFlag; - this.progress.percent = this.zeroFlag; - clearInterval(this.interval); - }, - changeDate(e) { - this.newDate = e.year + '-' + (e.month + this.oneFlag) + '-' + e.day; - }, - cancelDate() { - prompt.showToast({ - message: '取消' - }); - }, - changeCity(e) { - this.selectCityList = e.newValue; - this.selectCityString = e.newValue.join('-'); - }, - onMenuSelected(e) { - if (e.value === 'Item-1') { - this.$element('ratingDialog').show(); - } else if (e.value === 'Item-3') { - router.push({ - uri: "pages/viewsChart/viewsChart" - }); - } else if (e.value === 'Item-4') { - prompt.showToast({ - message: '程序退出中......' - }); - setTimeout(function () { - app.terminate(); - }, 2000); - } - }, - onTextClick() { - this.$element("apiMenu").show({ - x: 720, - y: 38 - }); - }, - cancelrRatingDialog() { - this.$element('ratingDialog').close(); - prompt.showToast({ - message: '取消......' - }); - }, - confirmRatingInfo() { - this.$element('ratingDialog').close(); - prompt.showToast({ - message: '评分:' + this.ratingNum + ' 评论理由:' + this.ratingReason - }); - }, - ratingChange(e) { - this.ratingNum = e.rating; + data: { + pageInfo: { + scoring: '评分', + sharing: '分享', + views: '浏览量', + exit: '退出', + annualPrice: '年货节 ¥9999', + productTitle: '【新品】HUAWEI MateBook X Pro 2021款', + productIntroduction: '13.9英寸全新11代酷睿i7 16G 512G 商务轻薄笔记本 3K触控全面屏 锐炬显卡 多屏协同 翡冷翠', + marqueeCustomData: '此商品活动中,请尽快购买!', + shipment: '发货', + nextDayReach: '次日达', + select: '选择', + rewardTo: '配送至:', + guarantee: '保障', + guaranteeContent: '假一赔一 - 满66包邮', + nowSell: '立即抢购', + inventory: '库存999件', + selectRewardTime: '选择配送时间:', + selectRewardCity: '选择配送城市:', + saleFlash: '抢购中', + justMoment: '请稍等......', + softwareScore: '软件评分', + ratingReason: '评分理由', + confirm: '确认', + cancel: '取消', + ratingPlaceholder: '请输入评分理由(非必填)' + }, + clearFlag: -1, + zeroFlag: 0, + oneFlag: 1, + twoFlag: 2, + threeFlag: 3, + fourFlag: 4, + textColor: '#FF3536', + flagNum: 0, + ratingReason: '', + ratingNum: 0, + scrollAmount: 10, + loop: '-1', + marqueeDir: 'right', + interval: null, + progress: { + percent: 0, + secondaryPercent: 0 + }, + swiperList: [1, 2, 3, 4, 5, 6, 7, 8], + swiperLists: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], + newDate: JSON.stringify(new Date()).substring(1, 11), + cityList: [['中国'], ['湖北省'], ['武汉市', '黄石市', '十堰市', '宜昌市', '襄阳市', '鄂州市', '荆门市' + , '孝感市', '荆州市', '黄冈市', '咸宁市', '随州市', '恩施', '仙桃市', '潜江市', '天门市', '神农架林区']], + selectCityList: [['中国'], ['湖北省'], ['武汉市']], + selectCityString: '', + contentList: [ + { + title: '屏幕尺寸', + content: '13.9英寸' + }, { + title: '运行内存', + content: '16GB' + }, { + title: '传播名', + content: 'HUAWEI MateBook X Pro' + }, { + title: '屏幕色彩', + content: '100% sRGB(典型值)' + }, { + title: '电池容量', + content: '56Wh(额定容量)' + }, { + title: '存储容量', + content: '512GB' + }, { + title: '分辨率', + content: '3000x2000' + }, { + title: 'CPU型号', + content: '第11代英特尔® 酷睿™ i5-1135G7 处理器' + }, { + title: 'CPU核数', + content: '4核' + }, { + title: '上市时间', + content: '2021年1月' + } + ] + }, + onInit() { + }, + onShow() { + this.selectCityString = this.selectCityList.join('-'); + }, + selectCity() { + this.$element('simpleDialog').show(); + prompt.showToast({ + message: '选择' + }); + }, + selectSafeguard() { + prompt.showToast({ + message: '保障' + }); + }, + cancelSchedule() { + this.$element('simpleDialog').close(); + prompt.showToast({ + message: 'close dialog' + }); + }, + backPage() { + router.push({ + uri: 'pages/homepage/homepage' + }); + }, + buy() { + const PROGRESSQUARTERS = 25; + const PROGRESSONEHALF = 50; + const PROGRESSTHREEQUARTERS = 75; + const PROGRESSONEPERCENT = 100; + if (this.flagNum === 0) { + this.textColor = '#27FF50'; + } else if (this.flagNum === this.oneFlag) { + this.textColor = '#A774FF'; + } else if (this.flagNum === this.twoFlag) { + this.textColor = '#FFF244'; + } else { + this.flagNum = this.clearFlag; + this.textColor = '#291CFF'; + } + this.flagNum += this.oneFlag; + this.$element('simpleDialog1').show(); + const interval = setInterval(() => { + if ((this.progress.secondaryPercent === PROGRESSQUARTERS || this.progress.secondaryPercent === PROGRESSONEHALF + || this.progress.secondaryPercent === PROGRESSTHREEQUARTERS) && this.progress.percent !== PROGRESSONEPERCENT) { + this.progress.percent += this.oneFlag; + this.progress.secondaryPercent += this.oneFlag; + } else if (this.progress.secondaryPercent === PROGRESSONEPERCENT + && this.progress.percent !== PROGRESSONEPERCENT) { + this.progress.percent += this.oneFlag; + this.progress.secondaryPercent = this.zeroFlag; + } else if (this.progress.secondaryPercent !== PROGRESSONEPERCENT) { + this.progress.secondaryPercent += this.oneFlag; + } else if (this.progress.percent === PROGRESSONEPERCENT + && this.progress.secondaryPercent === PROGRESSONEPERCENT) { + this.$element('simpleDialog').close(); prompt.showToast({ - message: e.rating + message: '抢购成功......' }); - }, - ratingReasonChange(e) { - this.ratingReason = e.text; + clearInterval(interval); + } else { prompt.showToast({ - message: JSON.stringify(e.text) + message: '正在处理中......' }); - }, - stickFloat() { + } + this.interval = interval; + }, 30); + }, + cancelBuyDialog() { + const PROGRESSONEPERCENT = 100; + if (this.progress.secondaryPercent === PROGRESSONEPERCENT && this.progress.percent === PROGRESSONEPERCENT) { + prompt.showToast({ + message: '抢购成功......' + }); + } + this.$element('simpleDialog').close(); + this.progress.secondaryPercent = this.zeroFlag; + this.progress.percent = this.zeroFlag; + clearInterval(this.interval); + }, + changeDate(e) { + this.newDate = e.year + '-' + (e.month + this.oneFlag) + '-' + e.day; + }, + cancelDate() { + prompt.showToast({ + message: '取消' + }); + }, + changeCity(e) { + this.selectCityList = e.newValue; + this.selectCityString = e.newValue.join('-'); + }, + onMenuSelected(e) { + if (e.value === 'Item-3') { + router.push({ + uri: 'pages/viewsChart/viewsChart' + }); + } else if (e.value === 'Item-4') { + prompt.showToast({ + message: '程序退出中......' + }); + setTimeout(function() { + app.terminate(); + }, 2000); } -} \ No newline at end of file + }, + onTextClick() { + this.$element('apiMenu').show({ + x: 720, + y: 38 + }); + }, + cancelRatingDialog() { + this.$element('ratingDialog').close(); + prompt.showToast({ + message: '取消......' + }); + }, + confirmRatingInfo() { + this.$element('ratingDialog').close(); + prompt.showToast({ + message: '评分:' + this.ratingNum + ' 评论理由:' + this.ratingReason + }); + }, + ratingChange(e) { + this.ratingNum = e.rating; + prompt.showToast({ + message: e.rating + }); + }, + ratingReasonChange(e) { + this.ratingReason = e.text; + prompt.showToast({ + message: JSON.stringify(e.text) + }); + }, + stickFloat() { + } +}; diff --git a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/viewsChart/viewsChart.hml b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/viewsChart/viewsChart.hml index 668bdd014f47691f1d35ea701e68c6c0050bec1b..88fa38e3a9e26d3aac2471460a9cc98f8dd8d547 100644 --- a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/viewsChart/viewsChart.hml +++ b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/viewsChart/viewsChart.hml @@ -17,11 +17,7 @@ - + - -
\ No newline at end of file diff --git a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/viewsChart/viewsChart.js b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/viewsChart/viewsChart.js index 7dfb453447ce72e8a13a47dfe1d81d3f69f2e6c5..b8de22e527e681e26675511d0e2cefc9440564cf 100644 --- a/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/viewsChart/viewsChart.js +++ b/JSUI/ShoppingOpenHarmony/entry/src/main/js/default/pages/viewsChart/viewsChart.js @@ -14,70 +14,69 @@ */ export default { - data: { - temp: 0, - lineData: [ - { - strokeColor: '#0081ff', - fillColor: '#cce5ff', - data: [763, 550, 551, 554, 731, 654, 525, 696, 595, 628, 791, 505, 613, 575, 475, 553, 491, 680, 657, 716], - gradient: true, - } - ], - lineOps: { - xAxis: { - lineStylemin: 0, - max: 20, - display: false, - }, - yAxis: { - min: 0, - max: 1000, - display: false - }, - series: { - lineStyle: { - width: "5px", - smooth: true, - }, - headPoint: { - shape: "circle", - size: 10, - strokeWidth: 1, - fillColor: '#ffffff', - strokeColor: "#2C4CFF", - display: true - }, - loop: { - margin: 2, - gradient: true, - }, - }, + data: { + temp: 0, + lineData: [ + { + strokeColor: '#0081ff', + fillColor: '#cce5ff', + data: [763, 550, 551, 554, 731, 654, 525, 696, 595, 628, 791, 505, 613, 575, 475, 553, 491, 680, 657, 716], + gradient: true + } + ], + lineOps: { + xAxis: { + max: 20, + display: false + }, + yAxis: { + min: 0, + max: 1000, + display: false + }, + series: { + lineStyle: { + width: '5px', + smooth: true }, - }, - onInit() { - this.autoAddData(); - }, - addData() { - this.$refs.linechart.append({ - serial: 0, - data: [Math.floor(Math.random() * 400) + 400] - }) - }, - autoAddData() { - setInterval(() => { - let temp = [Math.floor(Math.random() * 400) + 400]; - if (this.temp % 20 === 0) { - this.lineData[0].data = []; - this.lineData = this.lineData.slice(); - } else { - this.lineData[0].data.push(temp); - this.$refs.linechart.append({ - serial: 0, - data: temp - }); - } - this.temp++; - }, 800); + headPoint: { + shape: 'circle', + size: 10, + strokeWidth: 1, + fillColor: '#ffffff', + strokeColor: '#2C4CFF', + display: true + }, + loop: { + margin: 2, + gradient: true + } + } } -} \ No newline at end of file + }, + onInit() { + this.autoAddData(); + }, + addData() { + this.$refs.lineChart.append({ + serial: 0, + data: [Math.floor(Math.random() * 400) + 400] + }); + }, + autoAddData() { + setInterval(() => { + const temp = [Math.floor(Math.random() * 400) + 400]; + if (this.temp % 20 === 0) { + this.lineData[0].data = []; + this.lineData = this.lineData.slice(); + } else { + this.lineData[0].data.push(temp); + this.$refs.lineChart.append({ + serial: 0, + data: temp + }); + } + this.temp++; + }, 800); + } +}; diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001160725256.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001160725256.png new file mode 100644 index 0000000000000000000000000000000000000000..e907467c33b91c6702bb2af53f41adc75a68efa1 Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001160725256.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001191957374.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001191957374.png new file mode 100644 index 0000000000000000000000000000000000000000..7a664b0108058c6a882948f0f0709dcaefadfbcf Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001191957374.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192090980.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192090980.png new file mode 100644 index 0000000000000000000000000000000000000000..38d4c5dd193497a434f47ede46c89743a23f7b68 Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192090980.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192117266.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192117266.png new file mode 100644 index 0000000000000000000000000000000000000000..0e5474fe38d54627473d06bfff193bca562ad17f Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192117266.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192117334.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192117334.png new file mode 100644 index 0000000000000000000000000000000000000000..2c73f7027b5f8d633614b83a6629a1ba8f8e496d Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192117334.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192117336.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192117336.png new file mode 100644 index 0000000000000000000000000000000000000000..2732cb0aef3e99abefabed16f9f1b284b4a08b60 Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192117336.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192277310.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192277310.png new file mode 100644 index 0000000000000000000000000000000000000000..216c26dcd5b13aa52f61e1f65988af664924d408 Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192277310.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192437236.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192437236.png new file mode 100644 index 0000000000000000000000000000000000000000..8c09d555be0be88167914467b3100e28deba5b6e Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192437236.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192437304.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192437304.png new file mode 100644 index 0000000000000000000000000000000000000000..490369d4baae62463f45e540d81eed5cc4f0a20e Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001192437304.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001193059680.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001193059680.png new file mode 100644 index 0000000000000000000000000000000000000000..7f4afa6ff9aa5dca03baa83ffa7b26bf848ebb8b Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001193059680.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001206763755.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001206763755.png new file mode 100644 index 0000000000000000000000000000000000000000..8df985a83def6d65af1b6a594e184f3b0adb4001 Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001206763755.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001236757247.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001236757247.png new file mode 100644 index 0000000000000000000000000000000000000000..3ac2b262922d12f6468f7bdff243a8c77d07b296 Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001236757247.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001236757413.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001236757413.png new file mode 100644 index 0000000000000000000000000000000000000000..8c09d555be0be88167914467b3100e28deba5b6e Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001236757413.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001236917309.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001236917309.png new file mode 100644 index 0000000000000000000000000000000000000000..19193c0348272f159c49e40b88887fbf40fde34d Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001236917309.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237078267.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237078267.png new file mode 100644 index 0000000000000000000000000000000000000000..b5f2aaf9a61270cac252e7a22f61901e92897306 Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237078267.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237197221.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237197221.png new file mode 100644 index 0000000000000000000000000000000000000000..905aa1c0f032e9c778eedb212d6a024b126ab376 Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237197221.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237197311.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237197311.png new file mode 100644 index 0000000000000000000000000000000000000000..3ac2b262922d12f6468f7bdff243a8c77d07b296 Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237197311.png differ diff --git a/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237197743.png b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237197743.png new file mode 100644 index 0000000000000000000000000000000000000000..d5bcf96bb9f018fd50c99d361376e614eec35cab Binary files /dev/null and b/JSUI/ShoppingOpenHarmony/screenshots/device/zh-cn_image_0000001237197743.png differ diff --git "a/JSUI/ShoppingOpenHarmony/screenshots/device/\346\210\252\345\233\276.png" "b/JSUI/ShoppingOpenHarmony/screenshots/device/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/JSUI/ShoppingOpenHarmony/screenshots/device/\346\210\252\345\233\276.png" differ diff --git a/JSUI/SliderApplication/README.MD b/JSUI/SliderApplication/README.MD index dc308eb80a6ba71c09ff6243b6d8d81f9047727d..ba912b68c3d1bcf26eb2b597a5e6de2f5da81c9c 100644 --- a/JSUI/SliderApplication/README.MD +++ b/JSUI/SliderApplication/README.MD @@ -1,3 +1,356 @@ -# SliderApplication -简介 -• 此Demo使用JS UI中的slider、image组件和动画样式,实现拖拽slider控制风车图片的转速和大小。您可以通过设置slider的值改变image的转速和图片大小。 +# 1.介绍 + +OpenHarmony的ArkUI(基于JS扩展的类Web开发范式)提供了常用的接口和组件,开发者可以根据实际场景和开发需求,选用不同的组件和接口。本篇Codelab我们将一起开启ArkUI(基于JS扩展的类Web开发范式)基础组件的学习之路。本教程是基础组件之slider以及image的使用。 + +在本教程中,我们将会通过一个简单的样例,将slider组件和image组件进行结合,实现一个风车转动的效果,用户可以利用slider组件调节风车的大小和转动速度。效果如下图所示,开发者还可以根据自己的需求添加不同的效果。 + +![](figures/VID_20211228_154514-00_00_00-00_00_30.gif) + +## 应用场景 + +- 视频、音乐类应用调节音量等场景。 + +- 视频应用、系统应用调节屏幕亮度等场景。 + +# 2.相关概念 + +**[slider组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-slider.md):**滑动条组件,用来快速调节设置值,如音量、亮度等。 + +**[image组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-image.md):**图片组件,用来渲染展示图片。 + +**[div组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-container-div.md)**:基础容器组件,用作页面结构的根节点或将内容进行分组。 + +**[text组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-text.md):**文本组件,用于呈现一段信息。 + +**[animation-duration](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-common-animation.md):**动画样式。 + +# 3.搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 4.将组件添加到布局文件中 + +在这个任务中,我们需要完成程序页面的新建和设计,并将程序使用到的slider组件、image组件添加到布局文件index.hml中。在完成新建项目后,我们看到系统自动创建了pages.index目录,在这个目录下,我们找到index.hml文件,开始进行页面设计。 + +打开index.hml文件,默认代码使用div组件和text组件来共同呈现文本显示的效果,具体代码如下: + +``` +
+ + {{ $t('strings.hello') }} {{ title }} + +
+``` + +## image组件 + +开发者可以删除默认代码跟着接下来的步骤一起开发,整个布局文件使用div组件将页面进行划分,分别是上方的动画展示,和下方的操作控制。动画展示部分使用到image组件: + +![](figures/windfill1.jpg) + +``` +
+ +
+``` + +其中src属性用来表示风车图片的路径;style属性用来定义图片的大小,[animation-duration动画样式](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-common-animation.md)用来定义图形旋转一周所用的时间。三个属性具体的值定义在index.js中。 + +## slider组件 + +页面的下半部分由容器组件div、基础组件[text](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-text.md)、[slider](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-slider.md)共同组成。text组件用来显示“速度”、“缩放比例”文本,slider用来实现控制风车的转动速度以及风车缩放的大小: + +![](figures/1112131.jpg) + +``` +
+ + 速度:{{speed}} + + + + 缩放比例:{{imageSize}} + + +
+``` + +slider组件的相关属性说明可参考下表: + + + + + + + + + + + + + + + + + + + + + + + +

名称

+

类型

+

默认值

+

描述

+

min

+

number

+

0

+

滑动选择器的最小值。

+

max

+

number

+

100

+

滑动选择器的最大值。

+

value

+

number

+

0

+

滑动选择器的初始值。

+
+ + +onchange事件在滑动slider组件时候执行,具体的属性值以及相应事件的定义,会在任务四中具体介绍。下面是该部分的完整代码: + +``` +
+
+ +
+
+ + 速度:{{speed}} + + + + 缩放比例:{{imageSize}} + + +
+
+``` + +# 5.为页面设计样式 + +在这个任务中,我们将一起为写好页面添加样式,上面所有的组件,我们都定义了class属性,它对应的样式都定义在index.css中,有关css更多的知识可以参考[CSS语法参考](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-framework-syntax-css.md)。 + +## image组件部分样式 + +这部分定义了image-block容器的样式,以及image组件的样式。删掉默认代码后,在index.css中先添加如下代码: + +``` +/* 页面整体纵向布局 */ +.container { + flex-direction: column; +} +/* 图片区域布局 */ +.image-block { + height: 50%; + justify-content: center; /* 水平居中 */ + align-items: center; /* 垂直居中 */ +} +/* 图片布局 */ +image { + width: 150px; + height: 150px; + animation-name: Go; + animation-iteration-count: infinite; /* 图片不限旋转次数 */ + animation-timing-function: linear; /* 动画匀速转动 */ +} +/* 图片旋转角度:0到360° */ +@keyframes Go +{ + from { + transform:rotate(0deg); + } + to { + transform:rotate(360deg); + } +} +``` + +每个样式的具体含义,在注释中有较为详细的说明,值得注意的是@keyframes Go定义了动画的旋转角度为从0度旋转到360度。 + +## slider组件部分样式 + +这部分定义了slider-block容器、slider组件和text组件的样式,继续在index.css中添加如下代码: + +``` +/* 进度条区域布局 */ +.slider-block { + height: 50%; + justify-content: center; /* 水平居中 */ + align-items: center; /* 垂直居中 */ + flex-direction: column; +} +/* 进度条布局 */ +slider { + margin-bottom: 20px; +} +/* 文字布局 */ +text { + margin-bottom: 10px; + font-size: 20px; +} +``` + +# 6.为组件添加响应事件 + +接下来,我们一起来完成整个样例的最后一步:定义slider的响应事件和一些初始值,完成最后一个任务,风车才可以随意调节大小并且转动。 + +## 数据定义 + +我们已经已经提到了布局中组件初始值的定义,在index.js中首先添加如下代码: + +``` +export default { + data: { + title: '', + imgUrl: '/common/images/windmill.png', + animationDuration: '10000ms', + animationDurationNum: 10000, + speed: 50, + minSpeed: 0, + maxSpeed: 100, + imageSize: 1, + size: 0, + minSize: 0, + maxSize: 100 + }, +``` + +这些值的具体含义,可以参考如下表格: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

key

+

description

+

imgUrl

+

图片存放的路径。

+

animationDuration

+

图片转360度所用时间。

+

animationDurationNum

+

改变图片转速响应事件的速度初始值。

+

speed

+

图片转速初始值。

+

minSpeed

+

slider组件控制速度的最小值。

+

maxSpeed

+

slider组件控制速度的最大值。

+

imageSize

+

图像大小。

+

size

+

改变图像大小响应事件的图像初始值。

+

minSize

+

slider组件控制缩放比例的最小值。

+

maxSize

+

slider组件控制缩放比例的最大值。

+
+ + +## 事件 + +继续添加如下代码,实现改变风车的转速和大小: + +``` + // 改变转速 + changeValue(e) { + if (e.mode == 'end' || e.mode == 'click') { + this.speed = e.value; + this.animationDurationNum = 10000 - e.value * 95 ; + this.animationDuration = this.animationDurationNum + 'ms'; + } + }, + // 改变大小 + changeSize(e) { + if (e.mode == 'end' || e.mode == 'click') { + this.size = e.value; + this.imageSize = this.size / 40 < 1 ? 1 : this.size / 40; + + } + } +} +``` + +到此我们已经完成了所有的任务和代码的编写。 + +>![](public_sys-resources/icon-note.gif) **说明:** +>样例中我们使用了一张风车图片,它放在js/default/common.images目录下,命名为windmill.png + +# 7.恭喜你 + +在本篇Codelab中,我们主要为大家讲解了如下JS基础组件 + +- slider +- image + +通过一个代码示例,实现风车转速和大小的调节,从布局、样式、响应事件三个层面,逐步为大家进行代码讲解。希望通过本教程,各位开发者可以对以上基础组件具有更深刻的认识。 + +# 8.参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/JSUI/SliderApplication) \ No newline at end of file diff --git a/JSUI/SliderApplication/build.gradle b/JSUI/SliderApplication/build.gradle index 9cf74c205fc884ae2c6796ce2298ecbe3f40672d..c2c8bbaed13747b913f19cef893f515bc32d02a7 100644 --- a/JSUI/SliderApplication/build.gradle +++ b/JSUI/SliderApplication/build.gradle @@ -3,9 +3,10 @@ apply plugin: 'com.huawei.ohos.app' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 + supportSystem "standard" } - + buildscript { repositories { maven { @@ -16,8 +17,8 @@ buildscript { } } dependencies { - classpath 'com.huawei.ohos:hap:2.4.5.5' - classpath 'com.huawei.ohos:decctest:1.2.5.1' + classpath 'com.huawei.ohos:hap:3.0.3.4' + classpath 'com.huawei.ohos:decctest:1.2.6.0' } } diff --git a/JSUI/SliderApplication/entry/build.gradle b/JSUI/SliderApplication/entry/build.gradle index 813a93b10b3abe7de94ecf98c04dea6465caed7f..c9687aa63fd22c2dc8654b07c3564b6f26b828f9 100644 --- a/JSUI/SliderApplication/entry/build.gradle +++ b/JSUI/SliderApplication/entry/build.gradle @@ -18,5 +18,5 @@ ohos { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) - testImplementation 'junit:junit:4.13' + testImplementation 'junit:junit:4.13.1' } diff --git a/JSUI/SliderApplication/entry/src/main/config.json b/JSUI/SliderApplication/entry/src/main/config.json index ca42a324bbcfb3af649bcc9770deeaf300c88950..f47594883f240d0a2708cc6b17f0a22901ed47c5 100644 --- a/JSUI/SliderApplication/entry/src/main/config.json +++ b/JSUI/SliderApplication/entry/src/main/config.json @@ -36,6 +36,8 @@ "orientation": "unspecified", "name": "com.huawei.sliderapplication.MainAbility", "icon": "$media:icon", + "srcPath": "default", + "srcLanguage": "js", "description": "$string:mainability_description", "formsEnabled": false, "label": "$string:entry_MainAbility", diff --git a/JSUI/SliderApplication/figures/1112131.jpg b/JSUI/SliderApplication/figures/1112131.jpg new file mode 100644 index 0000000000000000000000000000000000000000..98af02495d0aa66877cf1f516ae2fb5bdb8ff061 Binary files /dev/null and b/JSUI/SliderApplication/figures/1112131.jpg differ diff --git a/JSUI/SliderApplication/figures/VID_20211228_154514-00_00_00-00_00_30.gif b/JSUI/SliderApplication/figures/VID_20211228_154514-00_00_00-00_00_30.gif new file mode 100644 index 0000000000000000000000000000000000000000..9528cb64790b9d0b3f58b0ac9d6cd192ac6ca88a Binary files /dev/null and b/JSUI/SliderApplication/figures/VID_20211228_154514-00_00_00-00_00_30.gif differ diff --git a/JSUI/SliderApplication/figures/windfill1.jpg b/JSUI/SliderApplication/figures/windfill1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..35427515c44a9f618cda6b6897119c61e68ddf35 Binary files /dev/null and b/JSUI/SliderApplication/figures/windfill1.jpg differ diff --git "a/JSUI/SliderApplication/figures/\345\217\226\347\211\210\346\234\254.png" "b/JSUI/SliderApplication/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/JSUI/SliderApplication/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/JSUI/SliderApplication/figures/\346\210\252\345\233\276.png" "b/JSUI/SliderApplication/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/JSUI/SliderApplication/figures/\346\210\252\345\233\276.png" differ diff --git a/JSUI/SliderApplication/public_sys-resources/icon-caution.gif b/JSUI/SliderApplication/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/SliderApplication/public_sys-resources/icon-caution.gif differ diff --git a/JSUI/SliderApplication/public_sys-resources/icon-danger.gif b/JSUI/SliderApplication/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/SliderApplication/public_sys-resources/icon-danger.gif differ diff --git a/JSUI/SliderApplication/public_sys-resources/icon-note.gif b/JSUI/SliderApplication/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/JSUI/SliderApplication/public_sys-resources/icon-note.gif differ diff --git a/JSUI/SliderApplication/public_sys-resources/icon-notice.gif b/JSUI/SliderApplication/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/JSUI/SliderApplication/public_sys-resources/icon-notice.gif differ diff --git a/JSUI/SliderApplication/public_sys-resources/icon-tip.gif b/JSUI/SliderApplication/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/JSUI/SliderApplication/public_sys-resources/icon-tip.gif differ diff --git a/JSUI/SliderApplication/public_sys-resources/icon-warning.gif b/JSUI/SliderApplication/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/SliderApplication/public_sys-resources/icon-warning.gif differ diff --git a/JSUI/SwitchApplication/README.md b/JSUI/SwitchApplication/README.md index 7481e729f14165d29966bebb24340944ea81318a..ee784efd3e3895dce9c86625ba115fb2cd0575d2 100644 --- a/JSUI/SwitchApplication/README.md +++ b/JSUI/SwitchApplication/README.md @@ -1,3 +1,403 @@ -# SwitchApplication -简介 -• 此Demo使用了JS UI中的switch、chart组件。 您可以通过切换switch开关设置chart图表数据静态或动态显示。 +# 1.介绍 + +OpenHarmony的ArkUI(基于JS扩展的类Web开发范式)提供了常用的接口和组件,开发者可以根据实际场景和开发需求,选用不同的组件和接口,本篇Codelab,我们将一起开启ArkUI(基于JS扩展的类Web开发范式)基础组件的学习之路。本教程是基础组件之switch、chart组件的使用。 + +在本教程中,我们将会通过一个简单的样例,将chart组件和switch组件进行结合,实现线形图、量规图、柱状图不同效果的展示,并通过switch切换chart组件数据的动静态显示。效果如下图所示,开发者还可以根据自己的需求添加不同的效果。 + +![](figures/IMG_20211228_155122.jpg) + +## 应用场景 + +- 运动健康、办公类应用,数据可视化等场景。 + +# 2.相关概念 + +**[switch组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-switch.md):**开关选择器,通过开关,开启或关闭某个功能。 + +**[chart组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-chart.md):**图表组件,用于呈现线形图、柱状图、量规图界面。 + +**[div组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-container-div.md)**:基础容器组件,用作页面结构的根节点或将内容进行分组。 + +**[text组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-text.md):**文本组件,用于呈现一段信息。 + +# 3.搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 4.将组件添加到布局文件中 + +在这个任务中,我们需要完成程序页面的新建和设计,并将程序使用到的switch、chart组件添加到布局文件index.hml中,在完成新建项目后,我们看到系统自动创建了pages.index目录,在这个目录下,我们找到index.hml文件,开始进行页面设计。 + +打开index.hml文件,默认代码使用div组件和text组件来共同呈现文本显示的效果,具体代码如下: + +``` +
+ + {{ $t('strings.hello') }} {{ title }} + +
+``` + +## switch组件 + +开发者可以删除index.hml中的默认代码,根据下述步骤一起开发,整个布局文件使用div组件将页面进行划分,定义switch组件有动态和静态两种切换方式,页面如下: + +![](figures/s1.jpg) ![](figures/s2.jpg) + +``` +
+ + +
+``` + +## chart组件 + +添加chart组件呈现线形图、量规图、柱状图三种类型的图表,页面如下: + +![](figures/成品.png) + +``` +
+ 利润 + + 年份 +
+
+ +
+
+ 销量 + + 年份 +
+``` + +# 5.为页面设计样式 + +在这个任务中,我们将一起为页面添加样式,上面所有的组件,我们都定义了class属性,它对应的样式都定义在index.css中,有关css更多的知识可以参考[CSS语法参考](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-framework-syntax-css.md)。 + +## switch组件部分样式 + +这部分定义了switch-block容器的样式,以及switch组件的样式。删掉默认代码后,在index.css中先添加如下代码: + +``` +.switch-block { + width: 98%; + height: 50px; +} +.switch { + text-padding: 10px; /* texton/textoff中最长文本两侧距离滑块边界的距离 */ + font-size: 12px; + texton-color: #5F5F5F; /* 选中字体颜色 */ + textoff-color: #707070; /* 未选中字体颜色 */ +} +``` + +## chart组件部分样式 + +这部分定义了chart组件线形图、量规图、柱状图三种类型的样式,在index.css中继续添加如下代码: + +``` +.chart-block, .gauge-block, .bar-block { + position: relative; + width: 98%; + border-radius: 5px; + background-color: #E3F8F9; +} +.text-speed{ + position: absolute; + top: 10px; + left: 20px; + width: 10px; + font-size: 10px; +} +.chart-data { + margin: 10px 5px 10px; + width: 100%; + height: 100px; +} +.text-time { + position: absolute; + font-size: 10px; + bottom: 2px; + right: 10px; +} +.gauge-block, .bar-block { + margin-top: 10px; +} +.data-gauge{ + width: 200%; + height: 200px; + margin: 10px 0 10px; /* 刻度条的宽度 */ + start-angle: 0; /* 起始角度 */ + total-angle: 360; /* 最大角度 */ + stroke-width: 20px; + colors: #CF0A2C, #8477DF, #17A98E; /* 颜色 */ + weights: 3, 2, 1; /* 颜色占比权重 */ +} +.data-bar { + width: 100%; + height: 200px; + margin: 10px 5px 10px; +} +``` + +# 6.为组件添加响应事件 + +## 数据定义 + +在之前的步骤中,我们已经提到了布局中组件初始值的定义,在index.js中首先添加如下代码: + +``` +export default { + data: { + interval: null, // 定时器对象 + showText: true, // 是否显示文本 + textOn: '动态', + textOff: '静态', + allowScale: true, // 文本尺寸跟随系统设置字体缩放 + dataLength: 5, // 数据长度 + barGroup: 3, // 柱状图组数 + + lineData: null, // 线形图数据 + lineOps: { // 线形图样式 + xAxis: { + min: 0, + max: 5, + display: true + }, + yAxis: { + min: 0, + max: 100, + display: true + }, + series: { + lineStyle: { + width: '1px', + smooth: true + }, + headPoint: { + shape: 'circle', + size: 10, + strokeWidth: 2, + fillColor: '#ffffff', + strokeColor: '#8477DF', + display: true + }, + loop: { + margin: 2 + } + } + }, + + percent: 100, // 量规图进度 + + barData: [ // 柱状图数据 + { + fillColor: '#CF0A2C', + data: [2, 20, 99, 56, 23] + }, + { + fillColor: '#8477DF', + data: [99, 88, 2, 67, 12] + }, + { + fillColor: '#17A98E', + data: [56, 2, 77, 99, 78] + } + ], + barOps: { // 柱状图样式 + xAxis: { + min: 0, + max: 20, + display: true, + axisTick: 5 + }, + yAxis: { + min: 0, + max: 100, + display: true + } + } + }, +} +``` + +这些值的具体含义,可以参考如下表格: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

key

+

description

+

interval

+

定时器对象。

+

showText

+

switch是否显示文本。

+

textOn

+

switch打开时显示内容。

+

textOff

+

switch关闭时显示内容。

+

dataLength

+

线形图、柱状图数据长度。

+

barGroup

+

柱状图组数。

+

lineData

+

线形图数据。

+

lineOps

+

线形图样式。

+

percent

+

量规图进度。

+

barData

+

柱状图数据。

+

barOps

+

柱状图样式。

+
+ + +## 事件 + +接下来继续添加如下代码,当switch开关发生变化时,触发change事件设置chart图片数据静态或动态。静态时chart组件显示静态数据,动态时利用interval定时器动态随机生成数据并显示,在export default中的data对象后面添加代码如下: + +``` +// 初始化 +onInit() { + this.changeLine(); +}, +change(e) { + if (e.checked) { + this.interval = setInterval(() => { + this.changeLine(); // 更新线形图数据 + this.changeGauge(); // 更新量规图数据 + this.changeBar(); // 更新柱状图数据 + }, 1000) + } else { + clearInterval(this.interval); + } +}, +// 更新线形图数据 +changeLine() { + var dataArray = []; + for (var i = 0; i < this.dataLength; i++) { + var nowValue = Math.floor(Math.random() * 99 + 1); + var obj = { + "value": nowValue, // Y坐标 + "description": nowValue + "", // 当前点的注释内容 + "textLocation": "top", // 注释内容位置 + "textColor": "#CDCACA", // 注释内容颜色 + "pointStyle": { // 节点形状 + "shape": "circle", // 形状 + "size": 5, // 形状大小 + "fillColor": "#CF0A2C", // 填充颜色 + "strokeColor": "#CF0A2C" // 边框颜色 + } + }; + dataArray.push(obj); + } + this.lineData = [ + { + strokeColor: '#17A98E', // 线的颜色 + data: dataArray, + gradient: false, + } + ] +}, +// 更新量规图数据 +changeGauge() { + this.percent = parseInt(this.percent) >= 99 ? 0 : parseInt(this.percent) + 1; + +}, +// 更新柱状图数据 +changeBar() { + for (var i=0;i![](public_sys-resources/icon-note.gif) **说明:** +>样例中当我们设置switch为动态时,使用setInterval定时器,每秒动态生成数据展示。 + +# 7.恭喜你 + +在本篇Codelab中,我们主要为大家讲解了如下JS基础组件 + +- switch +- chart + +通过一个代码示例,利用switch开关设置chart图形数据的动态变换,从布局、样式、响应事件三个层面,逐步为大家进行代码讲解,希望通过本教程,各位开发者可以对以上基础组件具有更深刻的认识。 + +# 8.参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/JSUI/SwitchApplication) \ No newline at end of file diff --git a/JSUI/SwitchApplication/build.gradle b/JSUI/SwitchApplication/build.gradle index 9cf74c205fc884ae2c6796ce2298ecbe3f40672d..c2c8bbaed13747b913f19cef893f515bc32d02a7 100644 --- a/JSUI/SwitchApplication/build.gradle +++ b/JSUI/SwitchApplication/build.gradle @@ -3,9 +3,10 @@ apply plugin: 'com.huawei.ohos.app' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 + supportSystem "standard" } - + buildscript { repositories { maven { @@ -16,8 +17,8 @@ buildscript { } } dependencies { - classpath 'com.huawei.ohos:hap:2.4.5.5' - classpath 'com.huawei.ohos:decctest:1.2.5.1' + classpath 'com.huawei.ohos:hap:3.0.3.4' + classpath 'com.huawei.ohos:decctest:1.2.6.0' } } diff --git a/JSUI/SwitchApplication/entry/build.gradle b/JSUI/SwitchApplication/entry/build.gradle index cccb71cae91018743841ab76aeb19c595f4ed847..c9687aa63fd22c2dc8654b07c3564b6f26b828f9 100644 --- a/JSUI/SwitchApplication/entry/build.gradle +++ b/JSUI/SwitchApplication/entry/build.gradle @@ -1,9 +1,9 @@ apply plugin: 'com.huawei.ohos.hap' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 defaultConfig { - compatibleSdkVersion 6 + compatibleSdkVersion 7 } buildTypes { release { @@ -14,10 +14,9 @@ ohos { } } - supportSystem "standard" } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) - testImplementation 'junit:junit:4.13' + testImplementation 'junit:junit:4.13.1' } diff --git a/JSUI/SwitchApplication/entry/src/main/config.json b/JSUI/SwitchApplication/entry/src/main/config.json index 94b41b26eaff5875a65d1ad96095333b0356918d..22364a3dde2c4792468af6d1fc5692d0127863f3 100644 --- a/JSUI/SwitchApplication/entry/src/main/config.json +++ b/JSUI/SwitchApplication/entry/src/main/config.json @@ -36,6 +36,8 @@ "orientation": "unspecified", "name": "com.huawei.switchapplication.MainAbility", "icon": "$media:icon", + "srcPath": "default", + "srcLanguage": "js", "description": "$string:mainability_description", "formsEnabled": false, "label": "$string:entry_MainAbility", diff --git a/JSUI/SwitchApplication/figures/IMG_20211228_155122.jpg b/JSUI/SwitchApplication/figures/IMG_20211228_155122.jpg new file mode 100644 index 0000000000000000000000000000000000000000..758071e056cab9c9dd6bbf6f30face1dad272f20 Binary files /dev/null and b/JSUI/SwitchApplication/figures/IMG_20211228_155122.jpg differ diff --git a/JSUI/SwitchApplication/figures/s1.jpg b/JSUI/SwitchApplication/figures/s1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2a4dd9447d4352d0a34802383e5e19251eccdb97 Binary files /dev/null and b/JSUI/SwitchApplication/figures/s1.jpg differ diff --git a/JSUI/SwitchApplication/figures/s2.jpg b/JSUI/SwitchApplication/figures/s2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d0f8776fa79a7b178f815a26688f082f830212b3 Binary files /dev/null and b/JSUI/SwitchApplication/figures/s2.jpg differ diff --git "a/JSUI/SwitchApplication/figures/\345\217\226\347\211\210\346\234\254.png" "b/JSUI/SwitchApplication/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/JSUI/SwitchApplication/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/JSUI/SwitchApplication/figures/\346\210\220\345\223\201.png" "b/JSUI/SwitchApplication/figures/\346\210\220\345\223\201.png" new file mode 100644 index 0000000000000000000000000000000000000000..867c7f9d4a267ae93a1385ed7c04651038668c25 Binary files /dev/null and "b/JSUI/SwitchApplication/figures/\346\210\220\345\223\201.png" differ diff --git "a/JSUI/SwitchApplication/figures/\346\210\252\345\233\276.png" "b/JSUI/SwitchApplication/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/JSUI/SwitchApplication/figures/\346\210\252\345\233\276.png" differ diff --git a/JSUI/SwitchApplication/public_sys-resources/icon-caution.gif b/JSUI/SwitchApplication/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/SwitchApplication/public_sys-resources/icon-caution.gif differ diff --git a/JSUI/SwitchApplication/public_sys-resources/icon-danger.gif b/JSUI/SwitchApplication/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/SwitchApplication/public_sys-resources/icon-danger.gif differ diff --git a/JSUI/SwitchApplication/public_sys-resources/icon-note.gif b/JSUI/SwitchApplication/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/JSUI/SwitchApplication/public_sys-resources/icon-note.gif differ diff --git a/JSUI/SwitchApplication/public_sys-resources/icon-notice.gif b/JSUI/SwitchApplication/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/JSUI/SwitchApplication/public_sys-resources/icon-notice.gif differ diff --git a/JSUI/SwitchApplication/public_sys-resources/icon-tip.gif b/JSUI/SwitchApplication/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/JSUI/SwitchApplication/public_sys-resources/icon-tip.gif differ diff --git a/JSUI/SwitchApplication/public_sys-resources/icon-warning.gif b/JSUI/SwitchApplication/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/JSUI/SwitchApplication/public_sys-resources/icon-warning.gif differ diff --git a/Media/ImageEditorTemplate/LICENSE b/Media/ImageEditorTemplate/LICENSE index 7c357dc828cf7d8c783f10ed6bb1bac8a1e903c1..80576ef141485b36eea4aebf25af97020bc2de44 100644 --- a/Media/ImageEditorTemplate/LICENSE +++ b/Media/ImageEditorTemplate/LICENSE @@ -1,10 +1,10 @@ - Copyright (c) 2021 Huawei Device Co., Ltd. + Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. - Licensed under the Apache License,Version 2.0 (the "License"); + 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 + 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, diff --git a/Media/ImageEditorTemplate/README.md b/Media/ImageEditorTemplate/README.md index e4066683adf7d09327b1fdf4c92d33e117150481..a4808d8f8ef50194783396f6e6ec8c7e598cd076 100644 --- a/Media/ImageEditorTemplate/README.md +++ b/Media/ImageEditorTemplate/README.md @@ -1,4 +1,529 @@ -# ImageEditorTemplate -简介 -• 本篇Codelab将为开发者介绍如何使用JS UI实现对图片的裁剪和调节两种编辑功能。应用主界面包含顶部区域、中间区域和底部区域。顶部区域由后退、撤销、重做以及保存image组件构成;中间区域由预览图、裁剪框构成;底部区域由上至下依次为:用于调节次级功能的编辑参数、用于选择次级功能、用于选择图片编辑功能。 +# 概述 + +本篇Codelab将为开发者介绍如何使用ArkUI实现对图片的裁剪和调节。应用主界面包含顶部区域、中间区域和底部区域。顶部区域由4个image组件\(后退、撤销、重做、保存\)和1个text组件(编辑)构成;中间区域由预览图、裁剪框构成;底部区域由上至下依次为:用于调节次级功能的编辑参数、用于选择次级功能、用于选择图片编辑功能。 + +效果图如下: + +![](figures/555.png) +# 相关概念 + +- [JS FA工程目录](#section245862185518) + +**[canvas组件](https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-canvas-canvas-0000000000621808)**:画布组件,用于自定义绘制图形。 + +**[slider组件](https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-basic-slider-0000000000611724)**:滑动条组件,用来快速调节设置值,如音量、亮度等。 + +## JS FA工程目录 +新建工程的JS目录如下图所示: + +![](figures/js.png) + +在工程目录中:i18n下存放多语言的json文件; + +- **main \> js \> default \> common \> images:**此文件夹存放一些图片资源。 +- **main \> js \> default \> i18n \> en-US.json:**此文件定义了英文模式下页面显示的变量内容。 +- **main \> js \> default \> i18n \> zh-CN.json:**此文件定义了中文模式下页面显示的变量内容。 +- **main \> js \> default \> pages \> index \> index.hml:**此文件定义了index页面的布局,包含index页面中的各个组件以及组件间的层级关系。 +- **main \> js \> default \> pages \> index \> index.css:**此文件定义了index页面的样式。 +- **main \> js \> default \> pages \> index \> index.js:**此文件定义了index页面的业务逻辑,比如数据绑定、事件处理等。 + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + + +# 实现页面布局和样式 + +在这个任务中,我们需要实现应用主界面的布局和样式。 + +## 顶部区域 + +由后退、撤销、重做以及保存image组件构成。 + +所需图片资源: + +![](figures/顶部.png) + +zh-CN.json文件定义: + +``` +titleAppBar :“编辑” +``` + +index.hml布局代码如下: + +``` + +
+ +
+ + {{ titleAppBar }} +
+ +
+ + + +
+
+``` + +点击后退,弹出提示框提示“是否放弃当前修改?”,index.hml布局如下: + +``` + + +
+
+ {{ title }} +
+
+ + +
+
+
+``` + +## 中间区域 + +由画布组件canvas绘制的预览图、8个div组件组成的裁剪框构成。 + +所需图片资源: + +![](figures/中间.png) + +index.hml布局代码如下: + +``` + +
+ + +
+
+
+
+
+
+
+
+
+
+
+``` + +## 底部区域 + +由上至下依次为:调节次级功能的编辑参数\(裁剪比例、调节系数\)、选择次级功能\(画幅、亮度、对比度和饱和度\)、选择图片编辑功能\(裁剪和调节\)。如下图: + +![](figures/444.png) + +所需图片资源: + +![](figures/底部.png) + +zh-CN.json文件定义: + +``` +"picFrame": "画幅", +"luminance": "亮度", +"contrast": "对比度", +"saturation": "饱和度", +"cropping": "裁剪", +"adjust": "调节" +``` + +选择裁剪功能时,index.hml布局代码如下所示: + +``` + +
+
+ + + + + + + + +
+
+ + + {{ picFrame }} +
+
+ + + + +
+
+ + {{ cropping }} + + {{ adjust }} +
+
+``` + +选择调节功能时,index.hml布局代码如下所示: + +``` + +
+ + + +
+ + + + + + +
+
+ + {{ luminance }} + + {{ contrast }} + + {{ saturation }} +
+
+ + + + +
+
+ + {{ cropping }} + + {{ adjust }} +
+
+``` + +# 图片编辑之裁剪 + +图片裁剪功能提供了原图、1:1、16:9、9:16等固定裁剪比例,结合画布组件canvas进行裁剪图片。本任务将以9:16裁剪比例为例,为大家讲解JS图片裁剪功能的实现。其他比例裁剪功能的实现,请参考[完整代码](完整代码.md)。 + +使用canvas组件绘制一张原图,尺寸大小为宽300,高224。绘制完成后,调整裁剪框的位置。 + +index.js代码如下所示: + +``` +// 画布canvas初始化图片 +onShow() { + const img = new Image(); + img.src = 'common/images/image.jpg'; + const el = this.$element('canvasOne'); + const ctx = el.getContext('2d'); + // 清除画布内容 + ctx.clearRect(this.zero, this.zero, this.canvasWidth, this.canvasHeight); + // 原图相对画布的上边距(画布高度减原图高度除2) + this.originalImageTop = (this.canvasWidth - this.originalImageHeight) / this.two; + // 绘制原始图片 + ctx.drawImage(img, this.zero, this.originalImageTop, this.originalImageWidth, this.originalImageHeight); + // 保存图片(后续调节图片亮度、对比度和饱和度restore) + this.brightnessImgData = ctx.getImageData(this.zero, this.zero, this.canvasWidth, this.canvasHeight); + this.contrastImgData = this.brightnessImgData; + this.saturationImgData = this.brightnessImgData; + ctx.save(); + // 裁剪框左边距(原图) + this.cropBoxLeftOne = (this.originalImageWidth - this.originalImageWidth) / this.two + this.offset; + // 裁剪框左边距(1:1) + this.cropBoxLeftTwo = (this.originalImageWidth - this.originalImageHeight) / this.two + this.offset; + // 裁剪框左边距(16:9) + this.cropBoxLeftThr = (this.originalImageWidth - this.originalImageWidth) / this.two + this.offset; + // 裁剪框左边距(9:16) + this.cropBoxLeftFou = (this.originalImageWidth - this.originalImageHeight * 9 / 16) / this.two + this.offset; + // 裁剪框上边距(原图;图片相对于画布) + this.cropBoxTopOne = this.originalImageTop; + // 裁剪框上边距(1:1;图片相对于画布) + this.cropBoxTopTwo = this.originalImageTop; + // 裁剪框上边距(16:9;图片相对于画布) + this.cropBoxTopThr = (this.canvasHeight - this.originalImageWidth * 9 / 16) / this.two; + // 裁剪框上边距(9:16;图片相对于画布) + this.cropBoxTopFou = this.originalImageTop; + // 绘制完成后图片宽高 + this.dWidth = this.originalImageWidth; + this.dHeight = this.originalImageHeight; + console.log('初始化onShow()绘制完图片宽:' + this.dWidth + '高:' + this.dHeight); +} +``` + +其中,画布组件宽和高均设置为300px,原图距离画布上边距为\(300-224\)/2,offset是画布左边距。调整好裁剪框之后,按照9:16比例裁剪并放大图片。 + +index.js代码如下: + +``` +cropFour() { + const el = this.$element('canvasOne'); + const ctx = el.getContext('2d'); + console.log('9:16比例裁剪cropFour()裁剪框宽:' + this.cropWidth + '高:' + this.cropHeight); + // 需要输出的区域的左上角x坐标、y坐标 + this.sx = (this.dWidth - this.cropWidth) / this.two; + this.sy = (this.cropImgMaxHeight - this.cropHeight) / this.two; + let imageData; + // 以当前canvas指定区域内的像素创建ImageData对象 + if (this.dHeight === this.cropImgMaxHeight && this.dWidth !== this.cropImgMaxWidth) { + imageData = ctx.getImageData(this.sx, this.sy, this.cropWidth + (this.cropImgMaxWidth - this.originalImageHeight * 9 / 16) / this.two, this.cropHeight); + } else { + imageData = ctx.getImageData(this.sx, this.sy, this.cropWidth, this.cropHeight); + } + // 删除指定区域内的绘制内容 + ctx.clearRect(this.zero, this.zero, this.canvasWidth, this.canvasHeight); + if (this.dWidth === this.cropImgMaxWidth) { + // 放大 + ctx.scale(this.cropImgMaxHeight / this.cropHeight, this.cropImgMaxHeight / this.cropHeight); + } + // 绘制时x轴偏移量 + if (this.dHeight === this.cropImgMaxHeight && this.dWidth !== this.cropImgMaxWidth) { + // 9:16裁剪后继续9:16裁剪 + this.dx = this.zero; + } else { + this.dx = (this.cropImgMaxWidth - this.cropWidth * (this.cropImgMaxHeight / this.cropHeight)) / (this.two * (this.cropImgMaxHeight / this.cropHeight)); + } + // 绘制时y轴偏移量 + this.dy = this.zero; + console.log('9:16比例裁剪cropThr()ImageData对象:' + imageData); + // 绘制图片 + ctx.putImageData(imageData, this.dx, this.dy); + // 图片宽度为最大宽度300 + if (this.dWidth === this.cropImgMaxWidth) { + ctx.scale(this.cropHeight / this.cropImgMaxHeight, this.cropHeight / this.cropImgMaxHeight); + } + // 保存图片 + this.brightnessImgData = ctx.getImageData(this.zero, this.zero, this.canvasWidth, this.canvasHeight); + this.contrastImgData = this.brightnessImgData; + this.saturationImgData = this.brightnessImgData; + ctx.save(); + // 裁剪后裁剪框距离左边距离(9:16) + this.cropBoxLeftFou = (this.cropImgMaxWidth - this.cropImgMaxHeight * 9 / 16) / this.two + this.offset; + // 裁剪后裁剪框距离左边距离(16:9) + this.cropBoxLeftThr = (this.cropImgMaxWidth - this.cropImgMaxHeight * 9 / 16) / this.two + this.offset; + // 裁剪后裁剪框距离左边距离(1:1) + this.cropBoxLeftTwo = (this.cropImgMaxWidth - this.cropImgMaxHeight * 9 / 16) / this.two + this.offset; + // 裁剪后裁剪框距离左边距离(原图) + this.cropBoxLeftOne = (this.cropImgMaxWidth - this.cropImgMaxHeight * 9 / 16) / this.two + this.offset; + // 裁剪后裁剪框距离上边距离(原图) + this.cropBoxTopOne = (this.cropImgMaxHeight - this.cropImgMaxHeight * 9 / 16 * 16 / 9) / this.two; + // 裁剪后裁剪框距离上边距离(1:1) + this.cropBoxTopTwo = (this.cropImgMaxHeight - this.cropImgMaxHeight * 9 / 16) / this.two; + // 裁剪后裁剪框距离上边距离(16:9) + this.cropBoxTopThr = (this.cropImgMaxHeight - this.cropImgMaxHeight * 9 / 16 * 9 / 16) / this.two; + // 裁剪后裁剪框距离上边距离(9:16) + this.cropBoxTopFou = (this.cropImgMaxHeight - this.cropImgMaxHeight * 9 / 16 * 16 / 9) / this.two; + // 裁剪完图片宽高等于裁剪比例缩放后宽高 + this.dHeight = this.cropImgMaxHeight; + this.dWidth = this.dHeight * 9 / 16; + console.log('9:16比例裁剪cropFour()后图片宽:' + this.dWidth + '高:' + this.dHeight); + // 裁剪框宽高等于裁剪完图片宽高 + this.cropWidth = this.dWidth; + this.cropHeight = this.dHeight; +} +``` + +# 图片编辑之调节 + +图片调节功能使用slider组件和canvas组件,实现对图片亮度、对比度和饱和度的调节。本任务将以亮度调节为例,为大家讲解JS图片调节功能的实现。其他调节功能的实,请参考[完整代码](完整代码.md)。 + +在图片调节中,亮度调节的实现是将所有像素点亮度值乘一个增强系数,改变图片HSV和RGB,使得图像整体变亮或者变暗。 + +图片亮度调节实现index.js代码如下: + +``` +// 亮度调节 +setBrightnessValue(e) { + if (e.mode === 'start') { + this.oldBrightnessValue = e.value; + } else if (e.mode === 'end') { + this.brightnessValue = e.value; + // 亮度调节值最大时,恢复裁剪后的图片 + if (e.value === this.sliderMaxValue) { + const test = this.$element('canvasOne'); + const ctx = test.getContext('2d'); + // 恢复图片 + ctx.restore(); + ctx.putImageData(this.brightnessImgData, this.zero, this.zero); + } else { + // 亮度调节系数(新亮度值比原来亮度值) + const adjustValue = e.value / this.oldBrightnessValue; + this.adjustBrightness(adjustValue); + this.oldBrightnessValue = e.value; + } + } +}, +adjustBrightness(value) { + const test = this.$element('canvasOne'); + const ctx = test.getContext('2d'); + // 获取当前ImageData对象 + const imgData = ctx.getImageData(this.zero, this.zero, this.canvasWidth, this.canvasHeight); + // 绘制返回的新ImageData对象 ctx.putImageData(this.changeBrightness(imgData, value), this.zero, this.zero); + }, +// 调节图片亮度 +changeBrightness(imgdata, value) { + const data = imgdata.data; + // 循环遍历图片上的像素点,通过rgb2hsv和hsv2rgb计算公式,算出新的hsv和rgb + for (let i = 0; i < data.length; i += 4) { + const hsv = this.rgb2hsv([data[i], data[i + 1], data[i + 2]]); + // 像素值乘以增强系数 + hsv[2] *= value; + const rgb = this.hsv2rgb([...hsv]); + data[i] = rgb[0]; + data[i + 1] = rgb[1]; + data[i + 2] = rgb[2]; + } + return imgdata; +}, +// RGB转HSV +rgb2hsv(arr) { + let rr; + let gg; + let bb; + const r = arr[0] / 255; + const g = arr[1] / 255; + const b = arr[2] / 255; + let h; + let s; + const v = Math.max(r, g, b); + const diff = v - Math.min(r, g, b); + const diffc = function(c) { + return (v - c) / 6 / diff + 1 / 2; + }; + if (diff === 0) { + h = s = 0; + } else { + s = diff / v; + rr = diffc(r); + gg = diffc(g); + bb = diffc(b); + if (r === v) { + h = bb - gg; + } else if (g === v) { + h = 1 / 3 + rr - bb; + } else if (b === v) { + h = 2 / 3 + gg - rr; + } + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } + return [Math.round(h * 360), Math.round(s * 100), Math.round(v * 100)]; +}, +// HSV转RGB +hsv2rgb(hsv) { + let _l = hsv[0]; + let _m = hsv[1]; + let _n = hsv[2]; + let newR; + let newG; + let newB; + if (_m === 0) { + _l = _m = _n = Math.round(255 * _n / 100); + newR = _l; + newG = _m; + newB = _n; + } else { + _m = _m / 100; + _n = _n / 100; + const p = Math.floor(_l / 60) % 6; + const f = _l / 60 - p; + const a = _n * (1 - _m); + const b = _n * (1 - _m * f); + const c = _n * (1 - _m * (1 - f)); + switch (p) { + case 0: + newR = _n; newG = c; newB = a; + break; + case 1: + newR = b; newG = _n; newB = a; + break; + case 2: + newR = a; newG = _n; newB = c; + break; + case 3: + newR = a; newG = b; newB = _n; + break; + case 4: + newR = c; newG = a; newB = _n; + break; + case 5: + newR = _n; newG = a; newB = b; + break; + } + newR = Math.round(255 * newR); + newG = Math.round(255 * newG); + newB = Math.round(255 * newB); + } + return [newR, newG, newB]; +} +``` + +# 总结 + +通过本篇Codelab,您可以学到: + +1. 利用canvas组件提供的方法,实现图片绘制、裁剪、缩放、保存和恢复。 +2. 利用公式算法,结合silder调节值的大小,计算图片的HSV和RGB值,从而调节图片的亮度、对比度和饱和度。 + +# 编码挑战 + +本节提供了一个简单的家庭作业,用来测试您的学习情况。 + +## 目标 + +按1:1裁剪图片后顺时针旋转180度。 +# 完整代码 + +您可以点击下面的链接,查看工程的完整代码: + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/Media/ImageEditorTemplate) + + + + diff --git a/Media/ImageEditorTemplate/build.gradle b/Media/ImageEditorTemplate/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..c2c8bbaed13747b913f19cef893f515bc32d02a7 --- /dev/null +++ b/Media/ImageEditorTemplate/build.gradle @@ -0,0 +1,34 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + supportSystem "standard" +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } + dependencies { + classpath 'com.huawei.ohos:hap:3.0.3.4' + classpath 'com.huawei.ohos:decctest:1.2.6.0' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } +} diff --git a/Media/ImageEditorTemplate/entry/.gitignore b/Media/ImageEditorTemplate/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7d5b7a94f4dcf381f03ff21f28f8a2494b58023f --- /dev/null +++ b/Media/ImageEditorTemplate/entry/.gitignore @@ -0,0 +1,2 @@ +/build +/node_modules diff --git a/Media/ImageEditorTemplate/entry/build.gradle b/Media/ImageEditorTemplate/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..0f3cdb78317e1a442ae44748f49e28c9a113dc5b --- /dev/null +++ b/Media/ImageEditorTemplate/entry/build.gradle @@ -0,0 +1,25 @@ +apply plugin: 'com.huawei.ohos.hap' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + defaultConfig { + compatibleSdkVersion 7 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } + + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13' + ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.200' +} + diff --git a/Media/ImageEditorTemplate/entry/package.json b/Media/ImageEditorTemplate/entry/package.json new file mode 100644 index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/package.json @@ -0,0 +1 @@ +{} diff --git a/Media/ImageEditorTemplate/entry/proguard-rules.pro b/Media/ImageEditorTemplate/entry/proguard-rules.pro new file mode 100644 index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a --- /dev/null +++ b/Media/ImageEditorTemplate/entry/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/config.json b/Media/ImageEditorTemplate/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..f42d5127c28802d85afa21c5bde2e8c2c758475c --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/config.json @@ -0,0 +1,61 @@ +{ + "app": { + "bundleName": "com.huawei.cookbook", + "vendor": "huawei", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "com.huawei.imageeditortemplate", + "name": ".MyApplication", + "mainAbility": "com.huawei.imageeditortemplate.MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "visible": true, + "name": "com.huawei.imageeditortemplate.MainAbility", + "icon": "$media:icon", + "srcPath": "default", + "srcLanguage": "js", + "description": "$string:mainability_description", + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard", + "orientation": "portrait" + } + ], + "js": [ + { + "pages": [ + "pages/index/index" + ], + "name": "default", + "window": { + "designWidth": 720, + "autoDesignWidth": true + } + } + ] + } +} \ No newline at end of file diff --git a/Data/JsDistributedData/entry/src/main/js/default/app.js b/Media/ImageEditorTemplate/entry/src/main/js/default/app.js similarity index 100% rename from Data/JsDistributedData/entry/src/main/js/default/app.js rename to Media/ImageEditorTemplate/entry/src/main/js/default/app.js diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/Wallpaper.png b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/Wallpaper.png new file mode 100644 index 0000000000000000000000000000000000000000..60d4841a80eb20c63de74306cb7f8350d6a85c48 Binary files /dev/null and b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/Wallpaper.png differ diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/adjust_blue.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/adjust_blue.svg new file mode 100644 index 0000000000000000000000000000000000000000..e08ca4c697f021deeee824a4f1a13312c6d70710 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/adjust_blue.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/adjust_white.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/adjust_white.svg new file mode 100644 index 0000000000000000000000000000000000000000..6b8e74d597d9f7513d6798e73fc6367e31f0422a --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/adjust_white.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/advance.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/advance.svg new file mode 100644 index 0000000000000000000000000000000000000000..f20f71bca6db131419c86baf26e5dc4e18baf061 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/advance.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/back.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/back.svg new file mode 100644 index 0000000000000000000000000000000000000000..2b534039d1a59673311412b22b50d7209caec72b --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/back.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/bg-tv.jpg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/bg-tv.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e2c07b9700afb5683696f5793e865efd7744e0e0 Binary files /dev/null and b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/bg-tv.jpg differ diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/contrast_blue.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/contrast_blue.svg new file mode 100644 index 0000000000000000000000000000000000000000..36df00071d8d4e0263b63ff7931336dcc54c6a9a --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/contrast_blue.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/contrast_white.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/contrast_white.svg new file mode 100644 index 0000000000000000000000000000000000000000..4066a25830364872b3ddbc84dfa0459f8ad78948 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/contrast_white.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/cut_blue.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/cut_blue.svg new file mode 100644 index 0000000000000000000000000000000000000000..22cf1f9c0d7d152b8694657ace1f6a9d53f6b028 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/cut_blue.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/cut_white.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/cut_white.svg new file mode 100644 index 0000000000000000000000000000000000000000..114666fa147f764d8b802e4b492eda4b7c2b0db7 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/cut_white.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/image.jpg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..907966897d75758937f7caa92265fcbc9e3cb840 Binary files /dev/null and b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/image.jpg differ diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/luminance_blue.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/luminance_blue.svg new file mode 100644 index 0000000000000000000000000000000000000000..40c3e8233b6ec8cb80ce043610280310a5d39f14 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/luminance_blue.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/luminance_white.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/luminance_white.svg new file mode 100644 index 0000000000000000000000000000000000000000..21c8cfb6185e63e9e239313db25ff519efbd5d8e --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/luminance_white.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/picture_frame_white.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/picture_frame_white.svg new file mode 100644 index 0000000000000000000000000000000000000000..d0cc5e68db8de02c07f864481b7eab411a9b90cc --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/picture_frame_white.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/picture_frame_white_blue.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/picture_frame_white_blue.svg new file mode 100644 index 0000000000000000000000000000000000000000..45a92f0728817ee0fd91f7c4146287d501e17005 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/picture_frame_white_blue.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_1-1_blue.png b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_1-1_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..2d7a7423d56492390f3da47b83d83a6d944e74ff Binary files /dev/null and b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_1-1_blue.png differ diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_1-1_white.png b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_1-1_white.png new file mode 100644 index 0000000000000000000000000000000000000000..fe9031fabc0733c5071660111118dbfe159d9b00 Binary files /dev/null and b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_1-1_white.png differ diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_16-9_blue.png b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_16-9_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..80724a54dccc746840f0f0b60180ec992a3e9ca1 Binary files /dev/null and b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_16-9_blue.png differ diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_16-9_white.png b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_16-9_white.png new file mode 100644 index 0000000000000000000000000000000000000000..88f1417440f2b3b2c2f76aca930cd960f2db43de Binary files /dev/null and b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_16-9_white.png differ diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_9-16_blue.png b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_9-16_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..ff52b1c1bda2658f3fdfee815175f73d959725eb Binary files /dev/null and b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_9-16_blue.png differ diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_9-16_white.png b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_9-16_white.png new file mode 100644 index 0000000000000000000000000000000000000000..67d5dc5b0579389aa5d8adfd90d41a0ff6814345 Binary files /dev/null and b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/proportions_9-16_white.png differ diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/rewind.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/rewind.svg new file mode 100644 index 0000000000000000000000000000000000000000..84a9de921f60a173d6354e0b960f8acc54776f9d --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/rewind.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/saturation_blue.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/saturation_blue.svg new file mode 100644 index 0000000000000000000000000000000000000000..dc17c10358c9f21c4228208f526140ab2b818db4 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/saturation_blue.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/saturation_white.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/saturation_white.svg new file mode 100644 index 0000000000000000000000000000000000000000..29f54844609d5508bf58c5dc0df78036929eaa3a --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/saturation_white.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/save.svg b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/save.svg new file mode 100644 index 0000000000000000000000000000000000000000..038ca9affad386588d3afc3c6c196b957ed4d311 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/common/images/save.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/i18n/en-US.json b/Media/ImageEditorTemplate/entry/src/main/js/default/i18n/en-US.json new file mode 100644 index 0000000000000000000000000000000000000000..e63c70d978a3a53be988388c87182f81785e170c --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/i18n/en-US.json @@ -0,0 +1,6 @@ +{ + "strings": { + "hello": "Hello", + "world": "World" + } +} \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/i18n/zh-CN.json b/Media/ImageEditorTemplate/entry/src/main/js/default/i18n/zh-CN.json new file mode 100644 index 0000000000000000000000000000000000000000..0ebda4546ead27ac45bc3c7655173038ee1b2a52 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/i18n/zh-CN.json @@ -0,0 +1,20 @@ +{ + "strings": { + "title": "是否放弃当前修改?", + "titleAppBar": "编辑", + "picFrame": "画幅", + "cropping": "裁剪", + "adjust": "调节", + "luminance": "亮度", + "contrast": "对比度", + "saturation": "饱和度", + "picFraImgSrc": "common/images/picture_frame_white_blue.svg", + "conBotFirImgSrc": "common/images/picture_frame_white.svg", + "conBotSecImgSrc": "common/images/proportions_1-1_white.png", + "conBotThrImgSrc": "common/images/proportions_16-9_white.png", + "conBotFouImgSrc": "common/images/proportions_9-16_white.png", + "luminanceImgSrc": "common/images/luminance_white.svg", + "contrastImgSrc": "common/images/contrast_white.svg", + "saturationImgSrc": "common/images/saturation_white.svg" + } +} \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/pages/index/index.css b/Media/ImageEditorTemplate/entry/src/main/js/default/pages/index/index.css new file mode 100644 index 0000000000000000000000000000000000000000..c9634898f67811c8084a4863beaada7a2432f783 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/pages/index/index.css @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2021 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. + */ +.container { + flex-direction: column; + width: 100%; + height: 100%; + align-content: center; + align-items: center; + background-color: #000000; +} +/* 顶部显示 */ +.container-top { + width: 100%; + position: absolute; + margin-top: 20px; +} +.container-appBar-left { + margin-left: 30px; + width: 80px; +} +.container-image-left { + height: 24px; + width: 24px; +} +.container-txt { + font-size: 16px; + margin-left: 16px; + color: #ffffff; +} +.container-appBar-right { + margin-left: 240px; +} +.container-image-right { + height: 24px; + width: 24px; + margin-left: 10px; +} +/* 弹窗退出应用 */ +.dialog-main { + width: 80%; + height: 16%; + margin-bottom: 30px; +} +.dialog-div { + flex-direction: column; + align-items: center; +} +.inner-txt { + flex-direction: column; + align-items: center; + margin-top: 16px; +} +.txt { + font-size: 16px; +} +.inner-btn { + height: 60px; + justify-content: space-around; + align-items: center; +} +.btn-cancel { + margin-left: 10px; +} +.btn-stop { + margin-left: 50px; +} +/* 裁剪部分 */ +#crop_image_content { + width: 100%; + position: absolute; + text-align: center; + margin-top: 130px; + margin-left: 75px; +} +#cropBox { + width: 100%; + position: absolute; +} +#crop_image_content #canvasOne { + position: absolute; + height: 300px; + width: 300px; + margin-left: 30px; + margin-right: 30px; + margin-bottom: 30px; +} +/* 裁剪框 */ +#crop_image_content #mainBox { + width: 100%; + border: 3px solid white; + position: absolute; + top: 0; + left: 0; +} +.minBox { + position: absolute; + height: 15px; + width: 3px; + background-color: #FF0000; +} +.left-up-top { + top: -3px; + left: -3px; + height: 3px; + width: 15px; +} +.left-up { + top: -3px; + left: -3px; +} +.right-up-top { + right: -3px; + top: -3px; + height: 3px; + width: 15px; +} +.right-up { + right: -3px; + top: -3px; +} +.left-down-bot { + bottom: -3px; + left: -3px; + height: 3px; + width: 15px; +} +.left-down { + bottom: -3px; + left: -3px; +} +.right-down-bot { + right: -3px; + bottom: -3px; + height: 3px; + width: 15px; +} +.right-down { + bottom: -3px; + right: -3px; +} +/* 裁剪比例 */ +.container-bottom-first { + width: 100%; + flex-direction: column; + position: absolute; + margin-top: 210px; +} +.container-bottom-one-first { + flex-direction: row; + margin-left: 40px; + margin-top: 250px; +} +.container-bottom-image { + height: 30px; + width: 30px; + margin-left: 100px; +} +.container-bottom-two-first { + flex-direction: column; + position: relative; + margin-left: 230px; + margin-top: 50px; +} +.container-bottom-three-first { + flex-direction: row; + margin-top: 70px; + margin-left: 120px; +} +.container-bottom-four-first { + flex-direction: row; + position: relative; + margin-left: 120px; + margin-bottom: 20px; +} +/* 调节比例 */ +.container-bottom-second { + flex-direction: column; + position: absolute; + margin-top: 210px; +} +.container-bottom-two-second { + flex-direction: row; +} +.container-bottom-three-second { + flex-direction: row; +} +.luminanceTxt { + font-size: 14px; + margin-left: 98px; +} +.contrastTxt { + font-size: 14px; + margin-left: 80px; +} +.saturationTxt { + font-size: 14px; + margin-left: 75px; +} +.container-bottom-four-second { + width: 100%; + margin-top: 60px; + flex-direction: row; + margin-left: 120px; +} +.container-bottom-five-second { + flex-direction: row; + position: relative; + margin-left: 120px; + margin-bottom: 20px; +} + +.container-bottom-second-one{ + flex-direction: column; + position: relative; + margin-top: 50px; +} diff --git a/Media/ImageEditorTemplate/entry/src/main/js/default/pages/index/index.hml b/Media/ImageEditorTemplate/entry/src/main/js/default/pages/index/index.hml new file mode 100644 index 0000000000000000000000000000000000000000..f90cc0eae15f0b104bbef655e9ee53e08884b796 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/js/default/pages/index/index.hml @@ -0,0 +1,125 @@ + +
+ + +
+
+ + {{ titleAppBar }} +
+
+ + + +
+
+ + +
+ + +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+ + + + +
+
+ + {{ picFrame }} +
+
+ + +
+
+ {{ cropping }} + {{ adjust }} +
+
+ + +
+
+ + + +
+
+
+ + + +
+
+ {{ luminance }} + {{ contrast }} + {{ saturation}} +
+
+ +
+ + +
+
+ {{ cropping }} + {{ adjust }} +
+
+ + + +
+
+ {{ title }} +
+
+ + +
+
+
+
diff --git a/Media/ImageEditorTemplate/entry/src/main/resources/base/element/string.json b/Media/ImageEditorTemplate/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..0bae6bd40f7360d5d818998221b199d3ec0f69c0 --- /dev/null +++ b/Media/ImageEditorTemplate/entry/src/main/resources/base/element/string.json @@ -0,0 +1,12 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "entry_MainAbility" + }, + { + "name": "mainability_description", + "value": "JS_Empty Ability" + } + ] +} \ No newline at end of file diff --git a/Media/ImageEditorTemplate/entry/src/main/resources/base/media/icon.png b/Media/ImageEditorTemplate/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/Media/ImageEditorTemplate/entry/src/main/resources/base/media/icon.png differ diff --git a/Media/ImageEditorTemplate/figures/444.png b/Media/ImageEditorTemplate/figures/444.png new file mode 100644 index 0000000000000000000000000000000000000000..c49a0506e1a894d1dca3284e79a5757589905eb4 Binary files /dev/null and b/Media/ImageEditorTemplate/figures/444.png differ diff --git a/Media/ImageEditorTemplate/figures/555.png b/Media/ImageEditorTemplate/figures/555.png new file mode 100644 index 0000000000000000000000000000000000000000..4e4e56de2a5d4cc312179044d5b67b6b82703ec1 Binary files /dev/null and b/Media/ImageEditorTemplate/figures/555.png differ diff --git a/Media/ImageEditorTemplate/figures/js.png b/Media/ImageEditorTemplate/figures/js.png new file mode 100644 index 0000000000000000000000000000000000000000..86456508e137254c9f1a43d2709af453a046c249 Binary files /dev/null and b/Media/ImageEditorTemplate/figures/js.png differ diff --git "a/Media/ImageEditorTemplate/figures/\344\270\255\351\227\264.png" "b/Media/ImageEditorTemplate/figures/\344\270\255\351\227\264.png" new file mode 100644 index 0000000000000000000000000000000000000000..5c063d8df9760c1617a49b2d5fb19472b02568e6 Binary files /dev/null and "b/Media/ImageEditorTemplate/figures/\344\270\255\351\227\264.png" differ diff --git "a/Media/ImageEditorTemplate/figures/\345\217\226\347\211\210\346\234\254.png" "b/Media/ImageEditorTemplate/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/Media/ImageEditorTemplate/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/Media/ImageEditorTemplate/figures/\345\272\225\351\203\250.png" "b/Media/ImageEditorTemplate/figures/\345\272\225\351\203\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..422e6da4a209b33952e0f49c1ed98f0a4944161b Binary files /dev/null and "b/Media/ImageEditorTemplate/figures/\345\272\225\351\203\250.png" differ diff --git "a/Media/ImageEditorTemplate/figures/\346\210\252\345\233\276.png" "b/Media/ImageEditorTemplate/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/Media/ImageEditorTemplate/figures/\346\210\252\345\233\276.png" differ diff --git "a/Media/ImageEditorTemplate/figures/\351\241\266\351\203\250.png" "b/Media/ImageEditorTemplate/figures/\351\241\266\351\203\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..56449f398023f7da5983383d2fa72b3af098e1fe Binary files /dev/null and "b/Media/ImageEditorTemplate/figures/\351\241\266\351\203\250.png" differ diff --git a/Media/ImageEditorTemplate/gradle/wrapper/gradle-wrapper.jar b/Media/ImageEditorTemplate/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9 Binary files /dev/null and b/Media/ImageEditorTemplate/gradle/wrapper/gradle-wrapper.jar differ diff --git a/Media/ImageEditorTemplate/gradle/wrapper/gradle-wrapper.properties b/Media/ImageEditorTemplate/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..f59159e865d4b59feb1b8c44b001f62fc5d58df4 --- /dev/null +++ b/Media/ImageEditorTemplate/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/Media/ImageEditorTemplate/public_sys-resources/icon-caution.gif b/Media/ImageEditorTemplate/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Media/ImageEditorTemplate/public_sys-resources/icon-caution.gif differ diff --git a/Media/ImageEditorTemplate/public_sys-resources/icon-danger.gif b/Media/ImageEditorTemplate/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Media/ImageEditorTemplate/public_sys-resources/icon-danger.gif differ diff --git a/Media/ImageEditorTemplate/public_sys-resources/icon-note.gif b/Media/ImageEditorTemplate/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/Media/ImageEditorTemplate/public_sys-resources/icon-note.gif differ diff --git a/Media/ImageEditorTemplate/public_sys-resources/icon-notice.gif b/Media/ImageEditorTemplate/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/Media/ImageEditorTemplate/public_sys-resources/icon-notice.gif differ diff --git a/Media/ImageEditorTemplate/public_sys-resources/icon-tip.gif b/Media/ImageEditorTemplate/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/Media/ImageEditorTemplate/public_sys-resources/icon-tip.gif differ diff --git a/Media/ImageEditorTemplate/public_sys-resources/icon-warning.gif b/Media/ImageEditorTemplate/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Media/ImageEditorTemplate/public_sys-resources/icon-warning.gif differ diff --git a/Media/ImageEditorTemplate/settings.gradle b/Media/ImageEditorTemplate/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07 --- /dev/null +++ b/Media/ImageEditorTemplate/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/Media/ImageJsDemo/README.md b/Media/ImageJsDemo/README.md index 636a619605e06e4fa665ae7a95b1959c831f07e9..86c4ce34b156374bca789ce71479250ddcf8079a 100644 --- a/Media/ImageJsDemo/README.md +++ b/Media/ImageJsDemo/README.md @@ -1,3 +1,306 @@ -# ImageJsDemo -简介 -• 此Demo使用JS UI中的Image组件,利用CSS实现图片的旋转,剪裁,缩放,镜像效果 +# 1.介绍 + +OpenHarmony ArkUI支持图片业务的开发,本Codelab以图片操作的旋转、剪裁、缩放、镜像四种常见操作为例,给大家介绍图像编辑操作。ArkUI是一种跨设备的高性能UI开发框架,支持声明式编程和跨设备多态UI。 + +本案例部署到Hi3516DV300开发板上的效果如下图所示: + +![](figures/IMG_20211008_150938.jpg) + +# 2.相关概念 + +**[image组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-image.md):**图片组件,用来渲染展示图片。 + +**[button组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-button.md)**:按钮组件,用于实现点击效果并实现点击触发事件。 + +**[div组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-container-div.md)**:基础容器组件,用作页面结构的根节点或将内容进行分组。 + +**[text组件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-basic-text.md):**文本组件,用于呈现一段信息。 + +# 3.搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境 + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + 3. 工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 4.代码结构解读 + +本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在[参考](参考.md)中提供下载方式,整个工程的代码结构如下: + +![](figures/结构.png) + +- common:存放公共资源 + +- index:构成图片操作的主页面 + + index.hml:布局文件 + + index.css:样式文件 + + index.js:逻辑处理文件 + +- config.json:配置文件 + +# 5.任务一:页面设计 + +在这个任务中,我们完成UI界面的设计,具体步骤: + +- 准备所使用的图片等相关资源。 +- 编写样式文件index.css。 +- 编写图形背景数据。 +- 编写主页面。 + +1. 在default/common/images 目录下放入案例要用到的图片: + + ![](figures/zh-cn_image_0000001165329578.png) + +2. 在src/main/js/default/pages/index/index.css中编写需要用到的样式,样式代码如下: + + ``` + .container { + justify-content: flex-start; + left: 0px; + top: 0px; + width: 100%; + height: 100%; + flex-direction: column; + } + .title { + font-size: 30px; + text-align: center; + width: 200px; + height: 100px; + justify-content: center; + align-items: center; + } + .title-div{ + width: 100%; + height: 100px; + align-items: center; + justify-content: center; + } + .button-div{ + justify-content: center; + height: 100px; + } + .button{ + margin: 10px; + font-size: 22px; + background-color: #e9e9e9; + text-color: black; + width: 180px; + text-align: center; + height: 120px; + } + .image-div{ + width: 100%; + justify-content: center; + margin-top: 100px; + } + .image{ + width: 576px; + height: 432px; + } + ``` + +3. 在src/main/js/default/pages/index/index.js中准备所需要用到的数据: + + ``` + data: { + // demo标题 + title: '图像开发', + // 图片资源位置 + imageUrl: '/common/images/shanghai.jpg', + // 是否旋转判定标志,默认为true + isRevolve: true, + // 是否剪裁判定标志,默认为false + isCut: false, + // 是否缩放判定标志,默认为false + isScale: false, + // 是否镜像判定标志,默认为false + isMirror: false, + // 用以记录旋转的角度(以图片组件中中心为旋转中心) + degrees: 0, + // 用以记录以y轴方向旋转的角度 + yDegrees: 0, + // 用以记录旋转次数(默认为0,最大为3,因为默认一次旋转90°,四次还原) + rotateIndex: 0, + // 图片宽度 + width: 576, + // 图片高度 + height: 488, + // 剪裁区域值数组(值分别指的是距离top, right, bottom, left 四个点的数值,默认都为0) + clipArray: [0, 0, 0, 0] + } + ``` + +4. 完成程序页面的新建和设计,将程序使用到的image组件添加到布局文件index.hml中: + + ``` +
+
+ + {{title}} + +
+
+ + + + +
+
+ + + + +
+
+ ``` + +# 6.任务二:添加交互事件 + +1. 为图片组件绑定数据: + + ``` +
+ + + + +
+ ``` + +2. 为4个button组件添加点击事件,分别实现点击旋转、剪裁、缩放、镜像的效果: + + ``` +
+ + + + +
+ ``` + +3. 在src/main/js/default/pages/index/index.js中实现相应方法: + + - 旋转 + + ``` + // 旋转 + imageRotate() { + if (!this.isRevolve) { + this.isRevolve = true; + this.isCut = false; + this.isScale = false; + this.isMirror = false; + this.rotateIndex = 0; + } + if (this.rotateIndex < 3) { + this.rotateIndex++; + } else { + this.rotateIndex = 0; + } + this.degrees = this.rotateIndex * 90; + } + ``` + + - 剪裁 + + ``` + // 剪裁 + imageCut() { + if (!this.isCut) { + this.isRevolve = false; + this.isCut = true; + this.isScale = false; + this.isMirror = false; + } + if (this.clipArray[2] === 0) { + // 值指的是 top, right, bottom, left 四个点 + this.clipArray = [0, 0, this.height / 2, 0]; + } else { + this.clipArray = [0, 0, 0, 0]; + } + } + ``` + + - 缩放 + + ``` + // 缩放 + imageScale() { + if (!this.isScale) { + this.isRevolve = false; + this.isCut = false; + this.isScale = true; + this.isMirror = false; + if (this.width === 576) { + this.width = this.width / 2; + this.height = this.height / 2; + } + } else { + if (this.width === 576) { + this.width = this.width / 2; + this.height = this.height / 2; + } else { + this.width = this.width * 2; + this.height = this.height * 2; + } + } + } + ``` + + - 镜像 + + ``` + // 镜像 + imageMirror() { + if (!this.isMirror) { + this.isRevolve = false; + this.isCut = false; + this.isScale = false; + this.isMirror = true; + this.yDegrees = 0; + } + if (this.yDegrees === 0) { + this.yDegrees = 180; + } else { + this.yDegrees = 0; + } + } + ``` + +# 7.恭喜你 + +恭喜你已经成功完成了本篇Codelab,并且学到了: + +- image组件的使用 +- button组件的使用 +- text组件的使用 +- 图片的旋转、剪裁、缩放、镜像四种常见操作 + +# 8.参考 + +[gitee地址](https://gitee.com/openharmony/codelabs/tree/master/Media/ImageJsDemo) \ No newline at end of file diff --git a/Media/ImageJsDemo/entry/build.gradle b/Media/ImageJsDemo/entry/build.gradle index cccb71cae91018743841ab76aeb19c595f4ed847..1587dd1948941f3eaaf092ae6cae7969cb6895ff 100644 --- a/Media/ImageJsDemo/entry/build.gradle +++ b/Media/ImageJsDemo/entry/build.gradle @@ -1,9 +1,9 @@ apply plugin: 'com.huawei.ohos.hap' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 defaultConfig { - compatibleSdkVersion 6 + compatibleSdkVersion 7 } buildTypes { release { @@ -13,11 +13,9 @@ ohos { } } } - - supportSystem "standard" } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) - testImplementation 'junit:junit:4.13' + testImplementation 'junit:junit:4.13.1' } diff --git a/Media/ImageJsDemo/figures/IMG_20211008_150938.jpg b/Media/ImageJsDemo/figures/IMG_20211008_150938.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0ce1d3a8cd445519f580588e0d041dd1520e3486 Binary files /dev/null and b/Media/ImageJsDemo/figures/IMG_20211008_150938.jpg differ diff --git a/Media/ImageJsDemo/figures/zh-cn_image_0000001165329578.png b/Media/ImageJsDemo/figures/zh-cn_image_0000001165329578.png new file mode 100644 index 0000000000000000000000000000000000000000..a8eed0839a12c56558d5365f59ee7623c4403486 Binary files /dev/null and b/Media/ImageJsDemo/figures/zh-cn_image_0000001165329578.png differ diff --git "a/Media/ImageJsDemo/figures/\345\217\226\347\211\210\346\234\254.png" "b/Media/ImageJsDemo/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/Media/ImageJsDemo/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/Media/ImageJsDemo/figures/\346\210\252\345\233\276.png" "b/Media/ImageJsDemo/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/Media/ImageJsDemo/figures/\346\210\252\345\233\276.png" differ diff --git "a/Media/ImageJsDemo/figures/\347\273\223\346\236\204.png" "b/Media/ImageJsDemo/figures/\347\273\223\346\236\204.png" new file mode 100644 index 0000000000000000000000000000000000000000..6b101b0cb85aa36188f3e0a039bace02efae9b20 Binary files /dev/null and "b/Media/ImageJsDemo/figures/\347\273\223\346\236\204.png" differ diff --git a/Media/ImageJsDemo/public_sys-resources/icon-caution.gif b/Media/ImageJsDemo/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Media/ImageJsDemo/public_sys-resources/icon-caution.gif differ diff --git a/Media/ImageJsDemo/public_sys-resources/icon-danger.gif b/Media/ImageJsDemo/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Media/ImageJsDemo/public_sys-resources/icon-danger.gif differ diff --git a/Media/ImageJsDemo/public_sys-resources/icon-note.gif b/Media/ImageJsDemo/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/Media/ImageJsDemo/public_sys-resources/icon-note.gif differ diff --git a/Media/ImageJsDemo/public_sys-resources/icon-notice.gif b/Media/ImageJsDemo/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/Media/ImageJsDemo/public_sys-resources/icon-notice.gif differ diff --git a/Media/ImageJsDemo/public_sys-resources/icon-tip.gif b/Media/ImageJsDemo/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/Media/ImageJsDemo/public_sys-resources/icon-tip.gif differ diff --git a/Media/ImageJsDemo/public_sys-resources/icon-warning.gif b/Media/ImageJsDemo/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Media/ImageJsDemo/public_sys-resources/icon-warning.gif differ diff --git a/Media/VideoOpenHarmony/README.md b/Media/VideoOpenHarmony/README.md index 924ae2138f7dcd886eb99777ce92cd5f1115ad7d..8fc025e632b3eb43c997f2112d75ef1778f3d747 100644 --- a/Media/VideoOpenHarmony/README.md +++ b/Media/VideoOpenHarmony/README.md @@ -1,12 +1,156 @@ -# VideoOpenHarmony +# 介绍 -VideoOpenHarmony +本篇Codelab我们将教会大家如何构建一个简易的OpenHarmony视频播放器(JS版本)。应用包含两级页面,分别是主页面和播放页面,两个页面都展示了丰富的JS UI组件。本教程将结合以下内容进行讲解: -我们最终会构建一个单机版本的视频播放器(JS版本)。应用包含两级页面,分别是主页面和播放页面,两个页面都展示了丰富的JS UI组件,本篇Codelab我们将会一起完成这个客户端,其中包括: -1.首页顶部swiper轮播图的使用 -2.首页底部list图片列表的使用 -3.播放页面video播放控件的使用 +1.主页面顶部使用swiper组件完成视频海报轮播 -本案例可以部署到OpenHarmony的开发环境上,部署效果如下图所示: +2.主页面底部使用list组件完成视频列表 -![](screenshots/device/videoPlayer.png) \ No newline at end of file +3.播放页面使用video组件完成视频播放 + +**本案例部署到OpenHarmony的开发环境上,部署效果如下图所示:** + +![](figures/zh-cn_image_0000001172234064.png) + +# 搭建OpenHarmony环境 + +完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**Hi3516DV300**开发板为例,参照以下步骤进行: + +1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制) + + 以3.0版本为例: + + ![](figures/取版本.png) + +2. 搭建烧录环境 + + 1. [完成DevEco Device Tool的安装](https://device.harmonyos.com/cn/docs/documentation/guide/install_windows-0000001050164976) + + 2. [完成Hi3516开发板的烧录](https://device.harmonyos.com/cn/docs/documentation/guide/hi3516_upload-0000001052148681) + +3. 搭建开发环境: + + 1. 开始前请参考[下载与安装软件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415)、[配置开发环境](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成DevEco Studio的安装和开发环境配置。 + 2. 开发环境配置完成后,请参考[使用工程工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md)创建工程,使用JS或者eTS语言开发、“Application”为例,模板选择“\[Standard\]Empty Ability”。 + + 3.工程创建完成后,可参考下面章节进行代码编写,使用真机进行调测: + + - [配置OpenHarmony应用签名信息](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md) + - [hap包安装指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/installing-openharmony-app.md) + - 工程示例: + + ![](figures/截图.png) + +# 代码结构解读 + +本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在最后的参考中提供下载方式,接下来我们会用一小节来讲解整个工程的代码结构: + +![](figures/截图106.png) + +- common:包含视频播放器所需要的图片资源和视频资源。 +- pages:用于存放所有页面的目录。 + - index:构成视频播放器的主页面,包括index.hml布局文件,index.css样式文件,index.js逻辑处理文件。 + - videopage:构成视频播放器的播放页面,包括videopage.hml布局文件,videopage.css样式文件,videopage.js逻辑处理文件。 + +- config.json:配置文件。 + +# 视频播放器主页面 + +首先,为视频播放器主页面添加一个海报轮播图,需要用到容器组件swiper,其提供了切换子组件显示的能力。代码如下所示: + +``` + +
+ +
+
+``` + +然后,为视频播放器主页面添加一个视频列表,需要用到容器组件list。列表是包含一系列相同宽度的列表项,适合连续、多行呈现同类数据,例如图片和文本,代码如下所示: + +``` + + + + + +``` + +最后,为图片的点击事件添加跳转逻辑,在点击图片后进入视频播放页面,代码如下所示: + +``` +import router from '@system.router'; +export default { + playVideo() { + router.push({ + uri: 'pages/videopage/videopage' + }); + } +} +``` + +# 视频播放器播放页面 + +JS视频播放器video组件的使用大家可以参考[【JS媒体组件】video的使用](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-media-video.md)进行学习,其中详细的给大家介绍了如何将video组件添加到布局中,如何为页面添加样式、如何为组件添加响应事件等操作。 + +要实现一个视频播放器的功能,首先需要在config.json添加配置,代码如下所示: + +``` +"module": { + ... + "abilities": [ + { + ... + "configChanges": ["orientation"] + } + ] +} +``` + +然后,我们需要在页面中添加一个video组件,代码如下所示: + +``` +
+ +
+``` + +最后,我们需要为video组件的onclick事件添加处理逻辑,代码如下所示: + +``` +export default { + data: { + isStart: true + }, + // 点击播放和暂停视频 + changeStartPause() { + if (this.isStart) { + this.$element('videoId').pause(); + this.isStart = false; + } else { + this.$element('videoId').start(); + this.isStart = true; + } + } +} +``` + +# 回顾和总结 + +本篇Codelab我们最终构建了一个JS版本的视频播放器,应用包含两级页面,分别是主页面和播放页面,两个页面都展示了丰富的JS UI组件,本篇Codelab我们学会了swiper、list容器组件的使用和video媒体组件的使用。 + +# 恭喜你 + +目前你已经成功完成了Codelab并且学到了: + +- 如何将一个JS项目部署到OpenHarmony设备上 + +- swiper组件的使用 +- list组件的使用 +- video组件的使用 + +# 参考 + +[gitee源码](https://gitee.com/openharmony/codelabs/tree/master/Media/VideoOpenHarmony) diff --git a/Media/VideoOpenHarmony/RELEASE-NOTES.md b/Media/VideoOpenHarmony/RELEASE-NOTES.md new file mode 100644 index 0000000000000000000000000000000000000000..ea23a13e3d4407d06cba3aa7155a23e5081b50b4 --- /dev/null +++ b/Media/VideoOpenHarmony/RELEASE-NOTES.md @@ -0,0 +1,2 @@ +1.0.0 +1.Initial version \ No newline at end of file diff --git a/Media/VideoOpenHarmony/build.gradle b/Media/VideoOpenHarmony/build.gradle index fa230b707f071d544736902167fda519b343d087..0f82325e371a2d3e2c8d36e530b24e75e202ace5 100644 --- a/Media/VideoOpenHarmony/build.gradle +++ b/Media/VideoOpenHarmony/build.gradle @@ -3,20 +3,21 @@ apply plugin: 'com.huawei.ohos.app' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 + supportSystem "standard" } - + buildscript { repositories { maven { - url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/' + url 'https://repo.huaweicloud.com/repository/maven/' } maven { - url 'http://mirrors.tools.huawei.com/maven/' + url 'https://developer.huawei.com/repo/' } } dependencies { - classpath 'com.huawei.ohos:hap:3.0.1.5' + classpath 'com.huawei.ohos:hap:3.0.3.4' classpath 'com.huawei.ohos:decctest:3.0.1.1' } } @@ -24,10 +25,10 @@ buildscript { allprojects { repositories { maven { - url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/' + url 'https://repo.huaweicloud.com/repository/maven/' } maven { - url 'http://mirrors.tools.huawei.com/maven/' + url 'https://developer.huawei.com/repo/' } } } diff --git a/Media/VideoOpenHarmony/entry/build.gradle b/Media/VideoOpenHarmony/entry/build.gradle index 6c2dca308825d3d38937c45c03918e1628bbfb75..945d62d4d0dafd6c0717e512607b0b07831c146c 100644 --- a/Media/VideoOpenHarmony/entry/build.gradle +++ b/Media/VideoOpenHarmony/entry/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.huawei.ohos.hap' //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 ohos { - compileSdkVersion 6 + compileSdkVersion 7 defaultConfig { compatibleSdkVersion 6 } @@ -14,7 +14,6 @@ ohos { } } - supportSystem "standard" } dependencies { diff --git a/Media/VideoOpenHarmony/entry/src/main/config.json b/Media/VideoOpenHarmony/entry/src/main/config.json index b4effbbe452b9b20cd21cb373b9c3ff0b5dffc97..480bc68eb3b8d7a1e4e015a5ec243cb1644a1784 100644 --- a/Media/VideoOpenHarmony/entry/src/main/config.json +++ b/Media/VideoOpenHarmony/entry/src/main/config.json @@ -11,7 +11,7 @@ "module": { "package": "com.huawei.video", "name": ".MyApplication", - "mainAbility": "com.huawei.video.MainAbility", + "mainAbility": ".MainAbility", "deviceType": [ "phone" ], @@ -35,13 +35,15 @@ ], "orientation": "unspecified", "visible": true, - "name": "com.huawei.video.MainAbility", + "name": ".MainAbility", "icon": "$media:icon", "description": "$string:mainability_description", "formsEnabled": false, "label": "$string:VideoDemo", "type": "page", - "launchType": "standard" + "launchType": "standard", + "srcPath": "mainAbility", + "srcLanguage": "js" } ], "js": [ @@ -50,7 +52,7 @@ "pages/index/index", "pages/videopage/videopage" ], - "name": "default", + "name": "mainAbility", "window": { "designWidth": 720, "autoDesignWidth": true diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/app.js b/Media/VideoOpenHarmony/entry/src/main/js/default/app.js deleted file mode 100644 index 6d060ffe5682c19fc83e2274a9e62cbc40a655f8..0000000000000000000000000000000000000000 --- a/Media/VideoOpenHarmony/entry/src/main/js/default/app.js +++ /dev/null @@ -1,8 +0,0 @@ -export default { - onCreate() { - console.info("Application onCreate"); - }, - onDestroy() { - console.info("Application onDestroy"); - } -}; diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/ic_tv.png b/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/ic_tv.png deleted file mode 100644 index 5374896a7f2c49f59b8e4445dda96790e3033e59..0000000000000000000000000000000000000000 Binary files a/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/ic_tv.png and /dev/null differ diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/i18n/en-US.json b/Media/VideoOpenHarmony/entry/src/main/js/default/i18n/en-US.json deleted file mode 100644 index 08e34eac912bf2651eefc20e26aa479b5e4e7ec2..0000000000000000000000000000000000000000 --- a/Media/VideoOpenHarmony/entry/src/main/js/default/i18n/en-US.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "strings": { - "hello": "Hello", - "world": "World", - "page": "Second Page", - "next": "Next Page", - "back": "Back" - }, - "Files": { - } -} \ No newline at end of file diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/i18n/zh-CN.json b/Media/VideoOpenHarmony/entry/src/main/js/default/i18n/zh-CN.json deleted file mode 100644 index 3dd53b3a8b808aec9396fa663cb00ef22ba61e0a..0000000000000000000000000000000000000000 --- a/Media/VideoOpenHarmony/entry/src/main/js/default/i18n/zh-CN.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "strings": { - "hello": "您好", - "world": "世界", - "page": "第二页", - "next": "下一页", - "back": "返回" - }, - "Files": { - } -} \ No newline at end of file diff --git a/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/app.js b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/app.js new file mode 100644 index 0000000000000000000000000000000000000000..eb885bb5eddc48644dc7b2ebdf1e9d000f089ea1 --- /dev/null +++ b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/app.js @@ -0,0 +1,6 @@ +export default { + onCreate() { + }, + onDestroy() { + } +}; diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/common/TestVideo.mp4 b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/TestVideo.mp4 similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/common/TestVideo.mp4 rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/TestVideo.mp4 diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/ic_next.png b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/ic_next.png similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/common/images/ic_next.png rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/ic_next.png diff --git a/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/icon.png b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/icon.png differ diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_ad0.jpg b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_ad0.jpg similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_ad0.jpg rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_ad0.jpg diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_ad1.jpg b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_ad1.jpg similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_ad1.jpg rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_ad1.jpg diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_ad2.jpg b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_ad2.jpg similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_ad2.jpg rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_ad2.jpg diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_ad3.jpg b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_ad3.jpg similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_ad3.jpg rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_ad3.jpg diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_list0.jpg b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_list0.jpg similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_list0.jpg rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_list0.jpg diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_list1.jpg b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_list1.jpg similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_list1.jpg rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_list1.jpg diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_list2.jpg b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_list2.jpg similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/common/images/video_list2.jpg rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/common/images/video_list2.jpg diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/i18n/en-US.json b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/i18n/en-US.json similarity index 100% rename from Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/i18n/en-US.json rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/i18n/en-US.json diff --git a/Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/i18n/zh-CN.json b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/i18n/zh-CN.json similarity index 100% rename from Distributed/NewsDemo/entry/.preview/intermediates/res/debug/rich/assets/js/MainAbility/i18n/zh-CN.json rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/i18n/zh-CN.json diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/pages/index/index.css b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/index/index.css similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/pages/index/index.css rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/index/index.css diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/pages/index/index.hml b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/index/index.hml similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/pages/index/index.hml rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/index/index.hml diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/pages/index/index.js b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/index/index.js similarity index 92% rename from Media/VideoOpenHarmony/entry/src/main/js/default/pages/index/index.js rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/index/index.js index 1e63fd7bed173a516d6a47dae9819a22c2781310..8790ffd7670a5208fbeaaa28c3e2b6c2385a3707 100644 --- a/Media/VideoOpenHarmony/entry/src/main/js/default/pages/index/index.js +++ b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/index/index.js @@ -18,8 +18,8 @@ import router from '@system.router'; export default { playVideo() { router.push({ - uri: 'pages/videopage/videopage' + uri: 'pages/videopage/videopage', }); - } -} + }, +}; diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/pages/videopage/videopage.css b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/videopage/videopage.css similarity index 100% rename from Media/VideoOpenHarmony/entry/src/main/js/default/pages/videopage/videopage.css rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/videopage/videopage.css diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/pages/videopage/videopage.hml b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/videopage/videopage.hml similarity index 86% rename from Media/VideoOpenHarmony/entry/src/main/js/default/pages/videopage/videopage.hml rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/videopage/videopage.hml index 0383fe3542b551893477040e2233940dce5bd479..2b78df21f23dce01ec6da99f620bbbaf3da23634 100644 --- a/Media/VideoOpenHarmony/entry/src/main/js/default/pages/videopage/videopage.hml +++ b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/videopage/videopage.hml @@ -18,7 +18,6 @@ limitations under the License. poster='/common/images/video_list1.png' controls="true" onprepared='preparedCallback' onstart='startCallback' onpause='pauseCallback' onfinish='finishCallback' onerror='errorCallback' onseeking='seekingCallback' onseeked='seekedCallback' - ontimeupdate='timeupdateCallback' - onlongpress='change_fullscreenchange' onclick="change_start_pause" loop='true' starttime="0"> + ontimeupdate='timeupdateCallback' onclick="changeStartPause" loop='true' starttime="0">
diff --git a/Media/VideoOpenHarmony/entry/src/main/js/default/pages/videopage/videopage.js b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/videopage/videopage.js similarity index 66% rename from Media/VideoOpenHarmony/entry/src/main/js/default/pages/videopage/videopage.js rename to Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/videopage/videopage.js index e55f86a67cd96945b6def764cbdd9a60d5ed5972..0a85538e754b3d5325a28d3fc922ce510ed42683 100644 --- a/Media/VideoOpenHarmony/entry/src/main/js/default/pages/videopage/videopage.js +++ b/Media/VideoOpenHarmony/entry/src/main/js/mainAbility/pages/videopage/videopage.js @@ -13,8 +13,6 @@ * limitations under the License. */ -import prompt from '@system.prompt'; - export default { data: { event: '', @@ -22,32 +20,31 @@ export default { timeupdatetime: '', seekedtime: '', isStart: true, - isfullscreenchange: false, duration: '', }, - preparedCallback: function (e) { + preparedCallback(e) { this.event = '视频连接成功'; this.duration = e.duration; }, - startCallback: function () { + startCallback() { this.event = '视频开始播放'; }, - pauseCallback: function () { + pauseCallback() { this.event = '视频暂停播放'; }, - finishCallback: function () { + finishCallback() { this.event = '视频播放结束'; }, - errorCallback: function () { + errorCallback() { this.event = '视频播放错误'; }, - seekingCallback: function (e) { + seekingCallback(e) { this.seekingtime = e.currenttime; }, - timeupdateCallback: function (e) { + timeupdateCallback(e) { this.timeupdatetime = e.currenttime; }, - change_start_pause: function () { + changeStartPause() { if (this.isStart) { this.$element('videoId').pause(); this.isStart = false; @@ -56,16 +53,4 @@ export default { this.isStart = true; } }, - start:async function() { - let actionData = { - }; - let target = { - bundleName: "com.huawei.video", - abilityName: "com.huawei.video.MainAbility", - data: actionData - }; - - let result = await FeatureAbility.startAbility(target); - let ret = JSON.parse(result); - } -} \ No newline at end of file +}; diff --git a/Media/VideoOpenHarmony/figures/zh-cn_image_0000001172234064.png b/Media/VideoOpenHarmony/figures/zh-cn_image_0000001172234064.png new file mode 100644 index 0000000000000000000000000000000000000000..8ee834ccb0eb28b6bce0c74e7926e3dbe90cdd16 Binary files /dev/null and b/Media/VideoOpenHarmony/figures/zh-cn_image_0000001172234064.png differ diff --git "a/Media/VideoOpenHarmony/figures/\345\217\226\347\211\210\346\234\254.png" "b/Media/VideoOpenHarmony/figures/\345\217\226\347\211\210\346\234\254.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a4203fdba7d630c4d6cf0b60685f27afd85d28a Binary files /dev/null and "b/Media/VideoOpenHarmony/figures/\345\217\226\347\211\210\346\234\254.png" differ diff --git "a/Media/VideoOpenHarmony/figures/\346\210\252\345\233\276.png" "b/Media/VideoOpenHarmony/figures/\346\210\252\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ce177f4d3e03464a38d31472b80e82775c68874 Binary files /dev/null and "b/Media/VideoOpenHarmony/figures/\346\210\252\345\233\276.png" differ diff --git "a/Media/VideoOpenHarmony/figures/\346\210\252\345\233\276106.png" "b/Media/VideoOpenHarmony/figures/\346\210\252\345\233\276106.png" new file mode 100644 index 0000000000000000000000000000000000000000..241e917be3ab9fc4b14363851bbdd0b4fccb36d4 Binary files /dev/null and "b/Media/VideoOpenHarmony/figures/\346\210\252\345\233\276106.png" differ diff --git a/Media/VideoOpenHarmony/public_sys-resources/icon-caution.gif b/Media/VideoOpenHarmony/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Media/VideoOpenHarmony/public_sys-resources/icon-caution.gif differ diff --git a/Media/VideoOpenHarmony/public_sys-resources/icon-danger.gif b/Media/VideoOpenHarmony/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Media/VideoOpenHarmony/public_sys-resources/icon-danger.gif differ diff --git a/Media/VideoOpenHarmony/public_sys-resources/icon-note.gif b/Media/VideoOpenHarmony/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/Media/VideoOpenHarmony/public_sys-resources/icon-note.gif differ diff --git a/Media/VideoOpenHarmony/public_sys-resources/icon-notice.gif b/Media/VideoOpenHarmony/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/Media/VideoOpenHarmony/public_sys-resources/icon-notice.gif differ diff --git a/Media/VideoOpenHarmony/public_sys-resources/icon-tip.gif b/Media/VideoOpenHarmony/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/Media/VideoOpenHarmony/public_sys-resources/icon-tip.gif differ diff --git a/Media/VideoOpenHarmony/public_sys-resources/icon-warning.gif b/Media/VideoOpenHarmony/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/Media/VideoOpenHarmony/public_sys-resources/icon-warning.gif differ diff --git a/README.md b/README.md index 93ba5de5bc4816623f3a95fd548185d12438ea52..2fba7b80031b96dc09ae8c2111245c1bf2be7451 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # OpenHarmony Codelabs - [概要简介](#section117915431558) -- [目录](#sectionMenu) +- [项目列表](#sectionMenu) - [使用说明](#section1954919258619) - [约束与限制](#section682025019613) - [相关仓](#section01752910717) @@ -31,7 +31,7 @@ | 16 | [OpenHarmony最小系统移植](https://gitee.com/openharmony/codelabs/tree/master/Device/PortingOpenHarmony) | 介绍如何移植一个最小操作系统,包括开发板配置、产品配置等等。 | | 17 | [HDF驱动模型Wi-Fi驱动](https://gitee.com/openharmony/codelabs/tree/master/Device/WifiDemo) | 基于HDF Wi-Fi模型,进行Wi-Fi的适配开发,实现了连接和交互功能。 | | 18 | [转场动画的使用(eTS)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/TransitionAnimtaionEts) | 基于OpenHarmony eTS UI转场动画,实现了页面间转场、组件内转场以及共享元素转场。 | -| 19 | [基础组件Slider的使用(eTS)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/SliderApplictionEts) | 基于OpenHarmony eTS UI,使用slider组件,实现可调节风车大小和转速的动画效果。 | +| 19 | [基础组件Slider的使用(eTS)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/SliderApplicationEts) | 基于OpenHarmony eTS UI,使用slider组件,实现可调节风车大小和转速的动画效果。 | | 20 | [image、image-animator(JS)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/ClickableJsDemo) | 基于OpenHarmony JS UI,使用Image、image-animator,实现图片展示与界面交互的动态效果。 | | 21 | [动画样式(JS)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/AnimationDemo) | 基于OpenHarmony JS UI,使用动画样式实现平移、旋转、缩放以及透明度变化的效果。 | | 22 | [dialog(JS)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/DialogDemo) | 基于OpenHarmony JS UI,使用dialog组件实现几种常用的弹窗效果。 |