From beb0212cdc201471e08a222ce9de378a35e68ec8 Mon Sep 17 00:00:00 2001 From: duangavin123 Date: Thu, 4 May 2023 15:18:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: duangavin123 --- zh-cn/third-party-cases/Readme-CN.md | 10 +- .../third-party-cases/book-flip-animation.md | 263 ++++++++++++++++++ .../third-party-cases/figures/add-item.gif | Bin .../figures/book-flip-animation.gif | Bin .../figures/book-flip-logic.png | Bin .../third-party-cases/figures/delete-item.gif | Bin .../different-operations-one-component.gif | Bin .../how-to-add-delete-listitems.md | 7 +- ...ind-different-operations-for-one-bundle.md | 4 +- ...-different-operations-for-one-component.md | 133 +++++++++ .../how-to-group-contacts-with-alphabet.md | 3 +- .../operation-regulations.md | 0 ...73\351\241\265\345\212\250\346\225\210.md" | 263 ------------------ 13 files changed, 409 insertions(+), 274 deletions(-) create mode 100644 zh-cn/third-party-cases/book-flip-animation.md rename "zh-cn/third-party-cases/figures/\346\226\260\345\242\236\345\210\227\350\241\250.gif" => zh-cn/third-party-cases/figures/add-item.gif (100%) rename "zh-cn/third-party-cases/figures/\347\277\273\351\241\265\345\212\250\346\225\210\347\244\272\344\276\213\345\233\276.gif" => zh-cn/third-party-cases/figures/book-flip-animation.gif (100%) rename "zh-cn/third-party-cases/figures/\347\277\273\351\241\265\345\212\250\346\225\210.png" => zh-cn/third-party-cases/figures/book-flip-logic.png (100%) rename "zh-cn/third-party-cases/figures/\345\210\240\351\231\244\345\210\227\350\241\250.gif" => zh-cn/third-party-cases/figures/delete-item.gif (100%) rename "zh-cn/third-party-cases/figures/\347\233\270\345\220\214\345\255\220\347\273\204\344\273\266\344\270\215\345\220\214\344\270\232\345\212\241\351\200\273\350\276\221.gif" => zh-cn/third-party-cases/figures/different-operations-one-component.gif (100%) rename "zh-cn/third-party-cases/\345\246\202\344\275\225\345\256\236\347\216\260\345\210\227\350\241\250\351\241\271\347\232\204\346\226\260\345\242\236\345\222\214\345\210\240\351\231\244.md" => zh-cn/third-party-cases/how-to-add-delete-listitems.md (98%) rename "zh-cn/third-party-cases/\345\246\202\344\275\225\344\270\272\345\220\214\344\270\200\347\273\204\344\273\266\345\234\250\344\270\215\345\220\214\345\234\272\346\231\257\344\270\213\347\273\221\345\256\232\344\270\215\345\220\214\347\232\204\344\270\232\345\212\241\351\200\273\350\276\221.md" => zh-cn/third-party-cases/how-to-bind-different-operations-for-one-bundle.md (98%) create mode 100644 zh-cn/third-party-cases/how-to-bind-different-operations-for-one-component.md rename "zh-cn/third-party-cases/\345\246\202\344\275\225\346\214\211\345\255\227\346\257\215\345\210\206\347\273\204\345\261\225\347\244\272\350\201\224\347\263\273\344\272\272.md" => zh-cn/third-party-cases/how-to-group-contacts-with-alphabet.md (99%) rename "zh-cn/third-party-cases/\346\241\210\344\276\213\345\272\223\350\257\264\346\230\216.md" => zh-cn/third-party-cases/operation-regulations.md (100%) delete mode 100644 "zh-cn/third-party-cases/\345\246\202\344\275\225\351\200\232\350\277\207\346\230\276\347\244\272\345\212\250\347\224\273\345\256\236\347\216\260\344\271\246\347\261\215\347\277\273\351\241\265\345\212\250\346\225\210.md" diff --git a/zh-cn/third-party-cases/Readme-CN.md b/zh-cn/third-party-cases/Readme-CN.md index 5ce2b272c6..cf6327ce0b 100644 --- a/zh-cn/third-party-cases/Readme-CN.md +++ b/zh-cn/third-party-cases/Readme-CN.md @@ -2,15 +2,15 @@ 本目录为社区开发者提供OpenHarmony开发典型案例,包括应用开发案例和设备开发案例,主要面向开发者在开发过程中经常使用的功能及其开发场景,提供对应的经验总结、指导教程等。 -关于案例的引用规范和声明,请参考[案例库说明](案例库说明.md)。 +关于案例的引用规范和声明,请参考[案例库说明](operation-regulations.md)。 ## 案例目录 ### ArkUI -- [如何按字母分组展示联系人](如何按字母分组展示联系人.md) -- [如何实现列表项的新增和删除](如何实现列表项的新增和删除.md) -- [如何通过显示动画实现书籍翻页动效](如何通过显示动画实现书籍翻页动效.md) -- [如何为同一组件在不同场景下绑定不同的业务逻辑](如何为同一组件在不同场景下绑定不同的业务逻辑.md) +- [如何按字母分组展示联系人](how-to-group-contacts-with-alphabet.md) +- [如何实现列表项的新增和删除](how-to-add-delete-listitems.md) +- [如何通过显示动画实现书籍翻页动效](book-flip-animation.md) +- [如何为同一组件在不同场景下绑定不同的业务逻辑](how-to-bind-different-operations-for-one-bundle.md) diff --git a/zh-cn/third-party-cases/book-flip-animation.md b/zh-cn/third-party-cases/book-flip-animation.md new file mode 100644 index 0000000000..6d8d6b6e42 --- /dev/null +++ b/zh-cn/third-party-cases/book-flip-animation.md @@ -0,0 +1,263 @@ +## 如何通过显示动画实现书籍翻页动效 + +### 场景介绍 + +翻页动效是应用开发中常见的动效场景,常见的如书籍翻页、日历翻页等。本文就为大家举例讲解如何通过ArkUI提供的显示动画接口[animateTo](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/arkui-ts/ts-explicit-animation.md/)实现书籍翻页的效果。 + +### 效果呈现 + +本例最终实现效果如下: +![翻页动效示例图](figures/book-flip-animation.gif) + +### 环境要求 + +- IDE:DevEco Studio 3.1.1.301 +- SDK:3.2.2.6(API9) + +### 实现思路 + +如图,我们分上下两层、左右两侧建立4个文本组件(下文用A、B、C、D代称),左右两侧分别代表打开书籍的左右两面,上下两层堆叠放置。 +当B沿旋转轴旋转180度覆盖在A上时,就体现为翻页效果。一个翻页动作的完成包括以下几步: +1、B沿旋转轴旋转180度。 +2、B旋转时,D会在右侧显示出来,作为书籍的下一页,此时D承载的内容要变为下一页的内容。 +3、B旋转到左侧后,A承载的内容变为B的内容。 +4、由于A和B互为镜像,所以A显示为B的内容后,需要以A的中间为轴旋转180度。 +5、B重新旋转到右边,其承载的内容变为下一页的内容。 +***说明:C用来占位,不需要做动作。*** +连续重复上述动作即可实现连续翻页动效。 +![翻页动效](figures/book-flip-logic.png) + +### 开发步骤 + +1. 创建文本组件 + 首先,我们看到动效中用到了4个文本组件,我们可以定义一个文本组件,然后对其进行重复调用。创建时我们为其添加[rotate](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-transformation.md/)属性,用来控制组件的旋转。 + 由于各组件旋转的角度和旋转中心不同,需要父组件在调用时传入对应的参数,所以我们为对应变量添加[@Prop](https://docs.openharmony.cn/pages/v3.1/zh-cn/application-dev/ui/ts-component-states-prop.md/)装饰器,用来控制变量传递。具体代码如下: + ``` + @Component + struct BookCard{ + // 为变量添加@Prop装饰器,用于接收父组件的动态传参 + @Prop num:number + @Prop y_position:string + @Prop x_position:string + @Prop rotate_angle:number + build(){ + Text(`${this.num}`) + .fontWeight(FontWeight.Bold) + .backgroundColor('#18183C') + .fontColor('white') + .fontSize(80) + .width('25%') + .height('30%') + .fontFamily('Monospace') + .textAlign(TextAlign.Center) + .borderRadius(20) + // 使用rotate属性控制旋转 + .rotate({ + x: 0, + y: 1, + z: 0, + angle: this.rotate_angle, + centerY: this.y_position, + centerX: this.x_position + }) + } + } + ``` +2. 创建父组件框架 + 由于文本组件分为上下两层,所以我们在父组件中采用[Stack](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/arkui-ts/ts-container-stack.md/)组件进行层叠布局。同时使用[Divider](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-divider.md/)组件作为书籍两个页面间的分隔线。具体代码如下: + ``` + @Entry + @Component + struct BookAnimation { + + build(){ + Stack(){ + Row(){ + // 组件C + BookCard() + // 组件D + BookCard() + } + Row(){ + // 组件A + BookCard() + // 组件B + BookCard() + } + // 添加两个页面间的分隔线 + Divider() + .strokeWidth(5) + .color('white') + .height('26%') + .vertical(true) + } + .width('100%') + .height('100%') + .backgroundColor('#A4AE77') + } + } + ``` + +3. 添加翻页动效 + + 最后我们通过以下几点来为静态的组件添加动效: + - 根据**实现思路**章节的分析,在父组件中定义对应的变量,并在调用子组件时分别传入子组件。 + - 自定义book_animate函数,在其中使用animateTo方法添加动画效果,同时控制动画的时长,以及动画过程中各元素状态的改变。 + - 在[aboutToAppear](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/ui/ui-ts-custom-component-lifecycle-callbacks.md/)方法中,使用[setInterval](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/apis/js-apis-timer.md/)方法重复调用book_animate函数,以实现连续翻页动效。 + 具体代码如下: + ``` + @Entry + @Component + struct BookAnimation { + // 父组件变量设置,注意使用@State做状态管理 + @State rotate_angle1:number = 0 + @State rotate_angle2:number = 0 + @State rotate_angle3:number = 0 + @State num_before: number = 0; + @State num: number = 1; + @State num_next: number = 0; + @State y_center1:string = '50%' + @State x_center1:string = '50%' + @State y_center2:string = '0%' + @State x_center2:string = '0%' + + // 在UI显示前,传入各项变量的具体值 + aboutToAppear() { + // 通过setInterval函数每秒调用一次动画效果,实现连续翻页 + setInterval(() => { + this.book_animate() + }, 1000)//函数调用周期要大于每次动画持续的时长 + } + + private book_animate(){ + // 通过animateTo方法为组件添加动效,动效时长要小于setInterval函数调用周期 + animateTo({ duration:700,onFinish:()=>{ + // 动画结束时,A显示的数字跟B显示的数字相等 + this.num_before = this.num + // 动画结束时,A以中心线为轴旋转180度 + this.rotate_angle3 = 180 + // 动画结束时,B返回至初始状态 + this.rotate_angle1 = 0 + // 动画结束时,B显示的数字加1 + this.num = (this.num + 1) % 10 + } + },()=>{ + // 动画开始,B的旋转角度变为180度 + this.rotate_angle1 = 180 + // 动画开始,D的数字加1 + this.num_next = this.num+1 + }) + } + + + build() { + Stack(){ + Row(){ + // C组件的引用配置 + BookCard({num:0,rotate_angle:this.rotate_angle2, + y_position:this.y_center2,x_position:this.x_center2}) + // D组件的引用配置 + BookCard({num:this.num_next,rotate_angle:this.rotate_angle2, + y_position:this.y_center2,x_position:this.x_center2}) + } + Row(){ + // A组件的引用配置 + BookCard({num:this.num_before,rotate_angle:this.rotate_angle3, + y_position:this.y_center1,x_position:this.x_center1}) + // B组件的引用配置 + BookCard({num:this.num,rotate_angle:this.rotate_angle1, + y_position:this.y_center2,x_position:this.x_center2}) + } + Divider().strokeWidth(5).color('white').height('26%').vertical(true) + }.width('100%').height('50%').backgroundColor('#A4AE77') + } + } + ``` + 通过以上步骤我们就可以实现翻页动效了。 + +### 完整代码 +示例完整代码如下: +``` +@Component +struct BookCard{ + @Prop num:number + @Prop y_position:string + @Prop x_position:string + @Prop rotate_angle:number + build(){ + Text(`${this.num}`) + .fontWeight(FontWeight.Bold) + .backgroundColor('#18183C') + .fontColor('white') + .fontSize(80) + .width('25%') + .height('30%') + .fontFamily('Monospace') + .textAlign(TextAlign.Center) + .borderRadius(20) + .rotate({ + x: 0, + y: 1, + z: 0, + angle: this.rotate_angle, + centerY: this.y_position, + centerX: this.x_position + }) + } +} + + +@Entry +@Component +struct BookAnimation { + @State rotate_angle1:number = 0 + @State rotate_angle2:number = 0 + @State rotate_angle3:number = 0 + @State num_before: number = 0; + @State num: number = 1; + @State num_next: number = 0; + @State y_center1:string = '50%' + @State x_center1:string = '50%' + @State y_center2:string = '0%' + @State x_center2:string = '0%' + + + aboutToAppear() { + setInterval(() => { + this.book_animate() + }, 1000) + } + + private book_animate(){ + animateTo({ duration:700,onFinish:()=>{ + this.num_before = this.num + this.rotate_angle3 = 180 + this.rotate_angle1 = 0 + this.num = (this.num + 1) % 10 + } + },()=>{ + this.rotate_angle1 = 180 + this.num_next = this.num+1 + }) + } + + + build() { + Stack(){ + Row(){ + BookCard({num:0,rotate_angle:this.rotate_angle2,y_position:this.y_center2, + x_position:this.x_center2}) + BookCard({num:this.num_next,rotate_angle:this.rotate_angle2,y_position:this.y_center2, + x_position:this.x_center2}) + } + Row(){ + BookCard({num:this.num_before,rotate_angle:this.rotate_angle3,y_position:this.y_center1, + x_position:this.x_center1}) + BookCard({num:this.num,rotate_angle:this.rotate_angle1,y_position:this.y_center2, + x_position:this.x_center2}) + } + Divider().strokeWidth(5).color('white').height('26%').vertical(true) + }.width('100%').height('50%').backgroundColor('#A4AE77') + } +} +``` diff --git "a/zh-cn/third-party-cases/figures/\346\226\260\345\242\236\345\210\227\350\241\250.gif" b/zh-cn/third-party-cases/figures/add-item.gif similarity index 100% rename from "zh-cn/third-party-cases/figures/\346\226\260\345\242\236\345\210\227\350\241\250.gif" rename to zh-cn/third-party-cases/figures/add-item.gif diff --git "a/zh-cn/third-party-cases/figures/\347\277\273\351\241\265\345\212\250\346\225\210\347\244\272\344\276\213\345\233\276.gif" b/zh-cn/third-party-cases/figures/book-flip-animation.gif similarity index 100% rename from "zh-cn/third-party-cases/figures/\347\277\273\351\241\265\345\212\250\346\225\210\347\244\272\344\276\213\345\233\276.gif" rename to zh-cn/third-party-cases/figures/book-flip-animation.gif diff --git "a/zh-cn/third-party-cases/figures/\347\277\273\351\241\265\345\212\250\346\225\210.png" b/zh-cn/third-party-cases/figures/book-flip-logic.png similarity index 100% rename from "zh-cn/third-party-cases/figures/\347\277\273\351\241\265\345\212\250\346\225\210.png" rename to zh-cn/third-party-cases/figures/book-flip-logic.png diff --git "a/zh-cn/third-party-cases/figures/\345\210\240\351\231\244\345\210\227\350\241\250.gif" b/zh-cn/third-party-cases/figures/delete-item.gif similarity index 100% rename from "zh-cn/third-party-cases/figures/\345\210\240\351\231\244\345\210\227\350\241\250.gif" rename to zh-cn/third-party-cases/figures/delete-item.gif diff --git "a/zh-cn/third-party-cases/figures/\347\233\270\345\220\214\345\255\220\347\273\204\344\273\266\344\270\215\345\220\214\344\270\232\345\212\241\351\200\273\350\276\221.gif" b/zh-cn/third-party-cases/figures/different-operations-one-component.gif similarity index 100% rename from "zh-cn/third-party-cases/figures/\347\233\270\345\220\214\345\255\220\347\273\204\344\273\266\344\270\215\345\220\214\344\270\232\345\212\241\351\200\273\350\276\221.gif" rename to zh-cn/third-party-cases/figures/different-operations-one-component.gif diff --git "a/zh-cn/third-party-cases/\345\246\202\344\275\225\345\256\236\347\216\260\345\210\227\350\241\250\351\241\271\347\232\204\346\226\260\345\242\236\345\222\214\345\210\240\351\231\244.md" b/zh-cn/third-party-cases/how-to-add-delete-listitems.md similarity index 98% rename from "zh-cn/third-party-cases/\345\246\202\344\275\225\345\256\236\347\216\260\345\210\227\350\241\250\351\241\271\347\232\204\346\226\260\345\242\236\345\222\214\345\210\240\351\231\244.md" rename to zh-cn/third-party-cases/how-to-add-delete-listitems.md index 687982235e..4b8b165702 100644 --- "a/zh-cn/third-party-cases/\345\246\202\344\275\225\345\256\236\347\216\260\345\210\227\350\241\250\351\241\271\347\232\204\346\226\260\345\242\236\345\222\214\345\210\240\351\231\244.md" +++ b/zh-cn/third-party-cases/how-to-add-delete-listitems.md @@ -1,5 +1,6 @@ ## 如何实现列表项的新增和删除 +### 场景介绍 列表的编辑模式用途十分广泛,常见于待办事项管理、文件管理、备忘录的记录管理等应用场景。在列表的编辑模式下,新增和删除列表项是最基础的功能,其核心是对列表项对应的数据集合进行数据添加和删除。 下面以待办事项管理为例,介绍如何快速实现新增和删除列表项功能。 @@ -14,7 +15,7 @@ **图17** 新增待办   -![新增列表](figures/新增列表.gif) +![新增列表](figures/add-item.gif) #### 开发步骤 @@ -84,9 +85,9 @@ 如下图所示,当用户长按列表项进入删除模式时,提供用户删除列表项选择的交互界面,用户勾选完成后点击删除按钮,列表中删除对应的项目。 - **图18** 长按删除待办事项   + **图18** 长按删除待办事项 -![删除列表](figures/删除列表.gif) +![删除列表](figures/delete-item.gif) #### 开发步骤 diff --git "a/zh-cn/third-party-cases/\345\246\202\344\275\225\344\270\272\345\220\214\344\270\200\347\273\204\344\273\266\345\234\250\344\270\215\345\220\214\345\234\272\346\231\257\344\270\213\347\273\221\345\256\232\344\270\215\345\220\214\347\232\204\344\270\232\345\212\241\351\200\273\350\276\221.md" b/zh-cn/third-party-cases/how-to-bind-different-operations-for-one-bundle.md similarity index 98% rename from "zh-cn/third-party-cases/\345\246\202\344\275\225\344\270\272\345\220\214\344\270\200\347\273\204\344\273\266\345\234\250\344\270\215\345\220\214\345\234\272\346\231\257\344\270\213\347\273\221\345\256\232\344\270\215\345\220\214\347\232\204\344\270\232\345\212\241\351\200\273\350\276\221.md" rename to zh-cn/third-party-cases/how-to-bind-different-operations-for-one-bundle.md index d8b22795e0..ad4b26de04 100644 --- "a/zh-cn/third-party-cases/\345\246\202\344\275\225\344\270\272\345\220\214\344\270\200\347\273\204\344\273\266\345\234\250\344\270\215\345\220\214\345\234\272\346\231\257\344\270\213\347\273\221\345\256\232\344\270\215\345\220\214\347\232\204\344\270\232\345\212\241\351\200\273\350\276\221.md" +++ b/zh-cn/third-party-cases/how-to-bind-different-operations-for-one-bundle.md @@ -16,8 +16,8 @@ 本示例将在一个页面中两次引用同一个按钮,然后为两次引用加入不同的处理逻辑,第一次引用中,点击按钮跳转到‘’Hello World!’‘页面;第二次引用中,点击按钮跳转到’‘Hello ArkTS!’‘页面。 #### 环境要求 -- IDE:DevEco Studio 3.1.1.301 -- SDK:3.2.2.6(API9) +- IDE:DevEco Studio 3.1 Beta1 +- SDK:Ohos_sdk_public 3.2.11.9 (API Version 9 Release) #### 开发步骤 **第1步 创建按钮组件** diff --git a/zh-cn/third-party-cases/how-to-bind-different-operations-for-one-component.md b/zh-cn/third-party-cases/how-to-bind-different-operations-for-one-component.md new file mode 100644 index 0000000000..30eb5ada0c --- /dev/null +++ b/zh-cn/third-party-cases/how-to-bind-different-operations-for-one-component.md @@ -0,0 +1,133 @@ +## 如何为同一组件在不同场景下绑定不同的业务逻辑 + +### 场景介绍 +我们在应用开发过程中经常遇到这样的场景:在不同的地方需要呈现同样的UI效果,为了简化处理,我们往往会把对应的UI元素封装成自定义组件,然后在用到的地方进行调用。但是,通常情况下,UI展示往往伴随着动态交互,而且在不同场景下需要做不同的交互处理。 +*比如:A、B两个页面都有返回按钮,但是在A页面中点击返回按钮是返回上一页,在B页面点击返回按钮是直接退出当前应用。同样是点击返回按钮,但是业务处理逻辑是不同的。* +那么在不同场景下调用同一组件的时候如何实现不同的交互逻辑呢?这就引出了本文要讲的内容。 + +### 实现思路 +要使同一组件实现不同效果,我们很容易就想到通过变量传参进行控制,而不是直接在程序中采用固定值,这样我们就可以根据不同场景传入不同参数从而实现不同效果。 +我们通常使用传参的方式改变组件的属性,比如:大小、边框、背景色、字体等等,同样的,我们也可以通过传参的方式改变组件绑定的业务逻辑,只不过,此时我们传入的是方法,然后在对应方法中写入具体的业务逻辑。 +接下来我们用一个简单的例子讲解如何实现。 + +### 开发示例 + +本示例将在一个页面中两次引用同一个按钮,然后为两次引用加入不同的处理逻辑,第一次引用中,点击按钮跳转到‘’Hello World!’‘页面;第二次引用中,点击按钮跳转到’‘Hello ArkTS!’‘页面。 + +#### 环境要求 +- IDE:DevEco Studio 3.1 Beta1 +- SDK:Ohos_sdk_public 3.2.11.9 (API Version 9 Release) + +#### 开发步骤 +1. 创建按钮组件 + 首先,让我们创建被引用的按钮组件。 + 这里需要注意的是,由于按钮要绑定不同的处理逻辑,所以我们在点击事件中不要写入固定的处理逻辑,而是传入一个自定义的空方法,该方法的逻辑在父组件中实现,然后传入。具体代码如下: + ``` + @Component + struct ChildComponent{ + @State button_text:string = 'hi' + // 定义一个空函数 + child_func:()=>void + build(){ + Button(`${this.button_text}`) + .height(100) + .width(200) + .onClick(() => { + // 在组件的点击事件中绑定之前定义的空函数 + this.child_func() + }) + } + } + ``` + +2. 在父组件中引用按钮组件 + 接下来,我们在父组件中引用两次第1步中创建的按钮组件。具体代码如下: + ``` + @Entry + @Component + struct FuncTransition{ + build() { + Column(){ + // 引用按钮组件 + ChildComponent({button_text:'Hello World'}) + .margin(50) + ChildComponent({button_text:'Hello ArkTS'}) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Center) + } + } + ``` + +3. 在父组件中传入处理逻辑 + 以上两步已经把我们的页面框架搭好了,接下来就是给按钮组件传入处理逻辑了,这也是最重要的一步。 + 我们在第1步中为按钮组件的点击事件绑定了一个空函数,现在我们在父组件中创建一个带有具体处理逻辑的函数,并将其传入按钮组件中。在父组件中可以通过为同一函数传入不同参数来为两个按钮组件绑定不同逻辑,也可以通过不同函数来实现,本例中采用前者进行实现。具体代码如下: + ``` + import router from '@ohos.router' + @Entry + @Component + struct FuncTransition{ + // 在父组件中创建逻辑处理函数,此处逻辑为页面跳转。 + parent_func(page_url){ + router.pushUrl({ + url:page_url + }) + } + build() { + Column(){ + // 在第1处引用的子组件中传入父组件中定义的函数,此处为跳转到''Hello World!''页面 + ChildComponent({child_func:()=>{this.parent_func('pages/HelloWorld')},button_text:'Hello World'}) + .margin(50) + // 在第2处引用的子组件中传入父组件中定义的函数,此处为跳转到''Hello ArkTS!''页面 + ChildComponent({child_func:()=>{this.parent_func('pages/HelloArkTS')},button_text:'Hello ArkTS'}) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Center) + } + } + ``` + + 通过以上步骤我们实现了在为同一按钮组件绑定不同的业务处理逻辑,接下来就让我们看下效果吧! + 注意:文中的‘’Hello World!’‘页面和’‘Hello ArkTS!’‘页面不是本文说明的重点,所以本文中不做开发介绍。 + ![相同子组件不同业务逻辑](figures/different-operations-one-component.gif) + +### 完整代码 +示例完整代码如下: +``` +import router from '@ohos.router' +@Entry +@Component +struct FuncTransition{ + parent_func(page_url){ + router.pushUrl({ + url:page_url + }) + } + build() { + Column(){ + ChildComponent({child_func:()=>{this.parent_func('pages/HelloWorld')},button_text:'Hello World'}) + .margin(50) + ChildComponent({child_func:()=>{this.parent_func('pages/HelloArkTS')},button_text:'Hello ArkTS'}) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Center) + } +} + +@Component +struct ChildComponent{ + @State button_text:string = 'hi' + child_func:()=>void + build(){ + Button(`${this.button_text}`) + .height(100) + .width(200) + .onClick(() => { + this.child_func() + }) + } +} +``` \ No newline at end of file diff --git "a/zh-cn/third-party-cases/\345\246\202\344\275\225\346\214\211\345\255\227\346\257\215\345\210\206\347\273\204\345\261\225\347\244\272\350\201\224\347\263\273\344\272\272.md" b/zh-cn/third-party-cases/how-to-group-contacts-with-alphabet.md similarity index 99% rename from "zh-cn/third-party-cases/\345\246\202\344\275\225\346\214\211\345\255\227\346\257\215\345\210\206\347\273\204\345\261\225\347\244\272\350\201\224\347\263\273\344\272\272.md" rename to zh-cn/third-party-cases/how-to-group-contacts-with-alphabet.md index 5d0d9c63d8..d0f528d1f8 100644 --- "a/zh-cn/third-party-cases/\345\246\202\344\275\225\346\214\211\345\255\227\346\257\215\345\210\206\347\273\204\345\261\225\347\244\272\350\201\224\347\263\273\344\272\272.md" +++ b/zh-cn/third-party-cases/how-to-group-contacts-with-alphabet.md @@ -6,13 +6,14 @@ ### 效果呈现 本示例最终效果如下: + ![contactlist](figures\contactlist.gif) ### 环境要求 - IDE:DevEco Studio 3.1 Beta1 - SDK:Ohos_sdk_public 3.2.11.9 (API Version 9 Release) -### 实现原理 +### 实现思路 本例涉及的四个关键特性及其实现方案如下: - 联系人按字母分组展示:通过List组件显示联系人列表,通过ListItemGroup组件实现联系人分组。 - 联系人右侧呈现字母导航:使用AlphabetIndexer组件实现字母导航,同时通过Stack组件使字母导航浮在联系人列表右侧。 diff --git "a/zh-cn/third-party-cases/\346\241\210\344\276\213\345\272\223\350\257\264\346\230\216.md" b/zh-cn/third-party-cases/operation-regulations.md similarity index 100% rename from "zh-cn/third-party-cases/\346\241\210\344\276\213\345\272\223\350\257\264\346\230\216.md" rename to zh-cn/third-party-cases/operation-regulations.md diff --git "a/zh-cn/third-party-cases/\345\246\202\344\275\225\351\200\232\350\277\207\346\230\276\347\244\272\345\212\250\347\224\273\345\256\236\347\216\260\344\271\246\347\261\215\347\277\273\351\241\265\345\212\250\346\225\210.md" "b/zh-cn/third-party-cases/\345\246\202\344\275\225\351\200\232\350\277\207\346\230\276\347\244\272\345\212\250\347\224\273\345\256\236\347\216\260\344\271\246\347\261\215\347\277\273\351\241\265\345\212\250\346\225\210.md" deleted file mode 100644 index 0bb88db111..0000000000 --- "a/zh-cn/third-party-cases/\345\246\202\344\275\225\351\200\232\350\277\207\346\230\276\347\244\272\345\212\250\347\224\273\345\256\236\347\216\260\344\271\246\347\261\215\347\277\273\351\241\265\345\212\250\346\225\210.md" +++ /dev/null @@ -1,263 +0,0 @@ -## 如何通过显示动画实现书籍翻页动效 - -### 场景介绍 - -翻页动效是应用开发中常见的动效场景,常见的如书籍翻页、日历翻页等。本文就为大家举例讲解如何通过ArkUI提供的显示动画接口[animateTo](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/arkui-ts/ts-explicit-animation.md/)实现书籍翻页的效果。 - -### 效果呈现 - -本例最终实现效果如下: -![翻页动效示例图](figures/翻页动效示例图.gif) - -### 环境要求 - -- IDE:DevEco Studio 3.1.1.301 -- SDK:3.2.2.6(API9) - -### 实现思路 - -如图,我们分上下两层、左右两侧建立4个文本组件(下文用A、B、C、D代称),左右两侧分别代表打开书籍的左右两面,上下两层堆叠放置。 -当B沿旋转轴旋转180度覆盖在A上时,就体现为翻页效果。一个翻页动作的完成包括以下几步: -1、B沿旋转轴旋转180度。 -2、B旋转时,D会在右侧显示出来,作为书籍的下一页,此时D承载的内容要变为下一页的内容。 -3、B旋转到左侧后,A承载的内容变为B的内容。 -4、由于A和B互为镜像,所以A显示为B的内容后,需要以A的中间为轴旋转180度。 -5、B重新旋转到右边,其承载的内容变为下一页的内容。 -***说明:C用来占位,不需要做动作。*** -连续重复上述动作即可实现连续翻页动效。 -![翻页动效](figures/翻页动效.png) - -### 开发步骤 - -#### 第1步,创建文本组件 -首先,我们看到动效中用到了4个文本组件,我们可以定义一个文本组件,然后对其进行重复调用。创建时我们为其添加[rotate](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-transformation.md/)属性,用来控制组件的旋转。 -由于各组件旋转的角度和旋转中心不同,需要父组件在调用时传入对应的参数,所以我们为对应变量添加[@Prop](https://docs.openharmony.cn/pages/v3.1/zh-cn/application-dev/ui/ts-component-states-prop.md/)装饰器,用来控制变量传递。具体代码如下: -``` -@Component -struct BookCard{ - // 为变量添加@Prop装饰器,用于接收父组件的动态传参 - @Prop num:number - @Prop y_position:string - @Prop x_position:string - @Prop rotate_angle:number - build(){ - Text(`${this.num}`) - .fontWeight(FontWeight.Bold) - .backgroundColor('#18183C') - .fontColor('white') - .fontSize(80) - .width('25%') - .height('30%') - .fontFamily('Monospace') - .textAlign(TextAlign.Center) - .borderRadius(20) - // 使用rotate属性控制旋转 - .rotate({ - x: 0, - y: 1, - z: 0, - angle: this.rotate_angle, - centerY: this.y_position, - centerX: this.x_position - }) - } -} -``` -#### 第2步,创建父组件框架 -由于文本组件分为上下两层,所以我们在父组件中采用[Stack](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/arkui-ts/ts-container-stack.md/)组件进行层叠布局。同时使用[Divider](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-divider.md/)组件作为书籍两个页面间的分隔线。具体代码如下: -``` -@Entry -@Component -struct BookAnimation { - - build(){ - Stack(){ - Row(){ - // 组件C - BookCard() - // 组件D - BookCard() - } - Row(){ - // 组件A - BookCard() - // 组件B - BookCard() - } - // 添加两个页面间的分隔线 - Divider() - .strokeWidth(5) - .color('white') - .height('26%') - .vertical(true) - } - .width('100%') - .height('100%') - .backgroundColor('#A4AE77') - } -} -``` - -#### 第3步,添加翻页动效 - -最后我们通过以下几点来为静态的组件添加动效: -- 根据**实现思路**章节的分析,在父组件中定义对应的变量,并在调用子组件时分别传入子组件。 -- 自定义book_animate函数,在其中使用animateTo方法添加动画效果,同时控制动画的时长,以及动画过程中各元素状态的改变。 -- 在[aboutToAppear](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/ui/ui-ts-custom-component-lifecycle-callbacks.md/)方法中,使用[setInterval](https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/apis/js-apis-timer.md/)方法重复调用book_animate函数,以实现连续翻页动效。 -具体代码如下: -``` -@Entry -@Component -struct BookAnimation { - // 父组件变量设置,注意使用@State做状态管理 - @State rotate_angle1:number = 0 - @State rotate_angle2:number = 0 - @State rotate_angle3:number = 0 - @State num_before: number = 0; - @State num: number = 1; - @State num_next: number = 0; - @State y_center1:string = '50%' - @State x_center1:string = '50%' - @State y_center2:string = '0%' - @State x_center2:string = '0%' - - // 在UI显示前,传入各项变量的具体值 - aboutToAppear() { - // 通过setInterval函数每秒调用一次动画效果,实现连续翻页 - setInterval(() => { - this.book_animate() - }, 1000)//函数调用周期要大于每次动画持续的时长 - } - - private book_animate(){ - // 通过animateTo方法为组件添加动效,动效时长要小于setInterval函数调用周期 - animateTo({ duration:700,onFinish:()=>{ - // 动画结束时,A显示的数字跟B显示的数字相等 - this.num_before = this.num - // 动画结束时,A以中心线为轴旋转180度 - this.rotate_angle3 = 180 - // 动画结束时,B返回至初始状态 - this.rotate_angle1 = 0 - // 动画结束时,B显示的数字加1 - this.num = (this.num + 1) % 10 - } - },()=>{ - // 动画开始,B的旋转角度变为180度 - this.rotate_angle1 = 180 - // 动画开始,D的数字加1 - this.num_next = this.num+1 - }) - } - - - build() { - Stack(){ - Row(){ - // C组件的引用配置 - BookCard({num:0,rotate_angle:this.rotate_angle2, - y_position:this.y_center2,x_position:this.x_center2}) - // D组件的引用配置 - BookCard({num:this.num_next,rotate_angle:this.rotate_angle2, - y_position:this.y_center2,x_position:this.x_center2}) - } - Row(){ - // A组件的引用配置 - BookCard({num:this.num_before,rotate_angle:this.rotate_angle3, - y_position:this.y_center1,x_position:this.x_center1}) - // B组件的引用配置 - BookCard({num:this.num,rotate_angle:this.rotate_angle1, - y_position:this.y_center2,x_position:this.x_center2}) - } - Divider().strokeWidth(5).color('white').height('26%').vertical(true) - }.width('100%').height('50%').backgroundColor('#A4AE77') - } -} -``` -通过以上步骤我们就可以实现翻页动效了。 - -### 完整代码 -示例完整代码如下: -``` -@Component -struct BookCard{ - @Prop num:number - @Prop y_position:string - @Prop x_position:string - @Prop rotate_angle:number - build(){ - Text(`${this.num}`) - .fontWeight(FontWeight.Bold) - .backgroundColor('#18183C') - .fontColor('white') - .fontSize(80) - .width('25%') - .height('30%') - .fontFamily('Monospace') - .textAlign(TextAlign.Center) - .borderRadius(20) - .rotate({ - x: 0, - y: 1, - z: 0, - angle: this.rotate_angle, - centerY: this.y_position, - centerX: this.x_position - }) - } -} - - -@Entry -@Component -struct BookAnimation { - @State rotate_angle1:number = 0 - @State rotate_angle2:number = 0 - @State rotate_angle3:number = 0 - @State num_before: number = 0; - @State num: number = 1; - @State num_next: number = 0; - @State y_center1:string = '50%' - @State x_center1:string = '50%' - @State y_center2:string = '0%' - @State x_center2:string = '0%' - - - aboutToAppear() { - setInterval(() => { - this.book_animate() - }, 1000) - } - - private book_animate(){ - animateTo({ duration:700,onFinish:()=>{ - this.num_before = this.num - this.rotate_angle3 = 180 - this.rotate_angle1 = 0 - this.num = (this.num + 1) % 10 - } - },()=>{ - this.rotate_angle1 = 180 - this.num_next = this.num+1 - }) - } - - - build() { - Stack(){ - Row(){ - BookCard({num:0,rotate_angle:this.rotate_angle2,y_position:this.y_center2, - x_position:this.x_center2}) - BookCard({num:this.num_next,rotate_angle:this.rotate_angle2,y_position:this.y_center2, - x_position:this.x_center2}) - } - Row(){ - BookCard({num:this.num_before,rotate_angle:this.rotate_angle3,y_position:this.y_center1, - x_position:this.x_center1}) - BookCard({num:this.num,rotate_angle:this.rotate_angle1,y_position:this.y_center2, - x_position:this.x_center2}) - } - Divider().strokeWidth(5).color('white').height('26%').vertical(true) - }.width('100%').height('50%').backgroundColor('#A4AE77') - } -} -``` -- GitLab