HarmonyOS实战开发-如何实现页面间转场动画

2024-03-29 19:44

本文主要是介绍HarmonyOS实战开发-如何实现页面间转场动画,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

介绍

在本教程中,我们将会通过一个简单的样例,学习如何基于ArkTS的声明式开发范式开发转场动画。其中包含页面间转场、组件内转场以及共享元素转场。效果如图所示:

说明: 本Codelab使用的display接口处于mock阶段,在预览器上使用会显示白屏现象,可选择在真机或模拟器上运行。

相关概念

  • 页面间转场:页面转场通过在全局pageTransition方法内配置页面入场组件和页面退场组件来自定义页面转场动效。
  • 组件内转场:组件转场主要通过transition属性进行配置转场参数,在组件插入和删除时进行过渡动效,主要用于容器组件子组件插入删除时提升用户体验(需要配合animateTo才能生效,动效时长、曲线、延时跟随animateTo中的配置)。
  • 共享元素转场:通过修改共享元素的sharedTransition属性设置元素在不同页面之间过渡动效。例如,如果两个页面使用相同的图片(但位置和大小不同),图片就会在这两个页面之间流畅地平移和缩放。

环境搭建

软件要求

  • DevEco Studio版本:DevEco Studio 3.1 Release。
  • OpenHarmony SDK版本:API version 9。

硬件要求

  • 开发板类型:润和RK3568开发板。
  • OpenHarmony系统:3.2 Release。

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)。以3.2 Release版本为例:

2.搭建烧录环境。

  1. 完成DevEco Device Tool的安装
  2. 完成RK3568开发板的烧录

3.搭建开发环境。

  1. 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
  2. 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”)。
  3. 工程创建完成后,选择使用真机进行调测。

代码结构解读

本篇Codelab只对核心代码进行讲解。

├──entry/src/main/ets                      // 代码区
│  ├──common
│  │  ├──constants
│  │  │  └──CommonConstants.ets            // 公共常量类
│  │  └──utils           
│  │     ├──DimensionUtil.ets              // 屏幕适配工具类
│  │     └──GlobalContext.ets              // 全局上下文工具类
│  ├──entryability
│  │  └──EntryAbility.ets                  // 程序入口类
│  ├──pages
│  │  ├──BottomTransition.ets              // 底部滑出页面
│  │  ├──ComponentTransition.ets           // 移动动画转场页面
│  │  ├──CustomTransition.ets              // 放缩动画转场页面
│  │  ├──FullCustomTransition.ets          // 旋转动画转场页面
│  │  ├──Index.ets                         // 应用首页
│  │  ├──ShareItem.ets                     // 共享元素转场部件
│  │  └──SharePage.ets                     // 共享元素转场页面
│  ├──view
│  │  ├──BackContainer.ets                 // 自定义头部返回组件
│  │  └──TransitionElement.ets             // 自定义动画元素
│  └──viewmodel
│     └──AnimationModel.ets                // 动画封装的model类
└──entry/src/main/resources                // 资源文件目录

构建主界面

在这个任务中,我们将完成主界面的设计和开发,效果如图所示:

从上面效果图可以看出,主界面主要由5个相同样式的功能菜单组成,我们可以将这些菜单抽取成一个子组件Item。

  1. 将所需要的图片添加到resources > base > media目录下。

2.在Index.ets中引入首页所需要图片和路由信息,声明子组件的UI布局并添加样式,使用ForEach方法循环渲染首页列表常量数据“INDEX_ANIMATION_MODE”,其中imgRes是设置按钮的背景图片,url用于设置页面路由的地址。

// Index.ets
import { INDEX_ANIMATION_MODE } from '../common/constants/CommonConstants';Column() {ForEach(INDEX_ANIMATION_MODE, (item: AnimationModel) => {Row().backgroundImage(item.imgRes).backgroundImageSize(ImageSize.Cover).backgroundColor($r('app.color.trans_parent')).height(DimensionUtil.getVp($r('app.float.main_page_body_height'))).margin({ bottom: DimensionUtil.getVp($r('app.float.main_page_body_margin')) }).width(FULL_LENGTH).borderRadius(BORDER_RADIUS).onClick(() => {router.pushUrl({ url: item.url }).catch((err: Error) => {hilog.error(DOMAIN, PREFIX, FORMAT, err);});})}, (item: AnimationModel) => JSON.stringify(item))
}

页面间转场

实现“底部滑入”效果

在BottomTransition申明pageTransition方法配置转场参数,其中PageTransitionEnter用于自定义当前页面的入场效果,PageTransitionExit用于自定义当前页面的退场效果。效果如图所示:

通过设置PageTransitionEnter和PageTransitionExit的slide属性为SlideEffect.Bottom,来实现BottomTransition入场时从底部滑入,退场时从底部滑出。

// BottomTransition.ets
@Entry
@Component
struct BottomTransition {build() {Column() {TransitionElement()}}/*** 页面转场通过全局pageTransition方法进行配置转场参数** SlideEffect.Bottom 入场时从屏幕下方滑入。* SlideEffect.Bottom 退场时从屏幕下方滑出。*/pageTransition() {PageTransitionEnter({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth }).slide(SlideEffect.Bottom);PageTransitionExit({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth }).slide(SlideEffect.Bottom);}
}

实现”页面转场:自定义1“效果

本节实现的效果,页面入场时为淡入和放大,退场时从右下角滑出。效果如图所示:

在CustomTransition.ets的Column组件中添加TransitionElement组件,并且定义pageTransition方法。

// CustomTransition.ets
@Entry
@Component
struct CustomTransition {build() {Column() {TransitionElement()}}/*** 页面转场通过全局pageTransition方法进行配置转场参数** 进场时透明度设置从0.2到1;x、y轴缩放从0变化到1* 退场时x、y轴的偏移量为500*/pageTransition() {PageTransitionEnter({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth }).opacity(CUSTOM_TRANSITION_OPACITY).scale(CUSTOM_TRANSITION_SCALE)PageTransitionExit({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth }).translate(CUSTOM_TRANSITION_TRANSLATE)}
}

说明: translate设置页面转场时的平移效果,为入场时起点和退场时终点的值,和slide同时设置时默认生效slide。

实现”页面转场:自定义2“动效

本节实现的效果,页面入场时淡入和放大,同时顺时针旋转;退场时淡出和缩小,同时逆时针旋转。效果如图所示:

在FullCustomTransition.ets的Column组件中添加TransitionElement组件,并且定义pageTransition方法。给Stack组件添加opacity、scale、rotate属性,定义变量animValue用来控制Stack组件的动效,在PageTransitionEnter和PageTransitionExit组件中动态改变myProgress的值。

// FullCustomTransition.ets
@Entry
@Component
struct FullCustomTransition {@State animValue: number = FULL_CUSTOM_TRANSITION_DEFAULT_ANIM_VALUE;build() {Column() {TransitionElement()}.opacity(this.animValue).scale({ x: this.animValue, y: this.animValue }).rotate({z: FULL_CUSTOM_TRANSITION_ROTATE_Z,angle: FULL_CUSTOM_TRANSITION_ANGLE * this.animValue})}/*** 页面转场通过全局pageTransition方法进行配置转场参数** 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0 - 1)* 进场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0 - 1)*/pageTransition() {PageTransitionEnter({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth }).onEnter((type?: RouteType, progress?: number) => {if (!progress) {return;}this.animValue = progress;});PageTransitionExit({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth }).onExit((type?: RouteType, progress?: number) => {if (!progress) {return;}this.animValue = FULL_CUSTOM_TRANSITION_DEFAULT_ANIM_VALUE - progress;});}
}

组件内转场

本节实现组件内转场动效,通过一个按钮来控制组件的添加和移除,呈现容器组件子组件添加和移除时的动效。效果如图所示:

组件转场主要通过transition属性方法配置转场参数,在组件添加和移除时会执行过渡动效,需要配合animateTo才能生效。动效时长、曲线、延时跟随animateTo中的配置。

  1. 在ComponentTransition.ets文件中,新建Image子组件,并添加两个transition属性,分别用于定义组件的添加动效和移除动效。
// ComponentTransition.ets
Image($r('app.media.bg_element')).TransitionEleStyles().transition({type: TransitionType.Insert,scale: COMPONENT_TRANSITION_SCALE,opacity: COMPONENT_TRANSITION_OPACITY}).transition({type: TransitionType.Delete,rotate: COMPONENT_TRANSITION_ROTATE,opacity: COMPONENT_TRANSITION_OPACITY})

2.在ComponentTransition代码中,定义一个isShow变量,用于控制Image子组件的添加和移除,在Button组件的onClick事件中添加animateTo方法,来使Image子组件子组件动效生效。

// ComponentTransition.ets
@State isShow: boolean = false;Button($r('app.string.Component_transition_toggle')).height(DimensionUtil.getVp($r('app.float.element_trans_btn_height'))).width(DimensionUtil.getVp($r('app.float.element_trans_btn_width'))).fontColor(Color.White).backgroundColor($r('app.color.light_blue')).onClick(() => {animateTo({ duration: TRANSITION_ANIMATION_DURATION }, () => {this.isShow = !this.isShow;})})

共享元素转场

效果如图所示:

共享元素转场通过给组件设置sharedTransition属性来实现,两个页面的组件配置为同一个id,则转场过程中会执行共享元素转场。sharedTransition可以设置动效的时长、动画曲线和延时,实现步骤如下:

  1. 在ShareItem.ets中给Image组件设置sharedTransition属性,组件转场id设置为“SHARE_TRANSITION_ID”。
// ShareItem.ets
Image($r('app.media.bg_transition')).width(FULL_LENGTH).height(DimensionUtil.getVp($r('app.float.share_item_element_height'))).borderRadius(DimensionUtil.getVp($r('app.float.share_item_radius'))).margin({ bottom: DimensionUtil.getVp($r('app.float.share_item_element_margin_bottom')) }).sharedTransition(SHARE_TRANSITION_ID, {duration: TRANSITION_ANIMATION_DURATION,curve: Curve.Smooth,delay: SHARE_ITEM_ANIMATION_DELAY}).onClick(() => {router.pushUrl({ url: SHARE_PAGE_URL }).catch((err: Error) => {hilog.error(DOMAIN, PREFIX, FORMAT, err);});})

2.在SharePage.ets中给Image组件设置sharedTransition属性,组件转场id设置为“SHARE_TRANSITION_ID”。

// SharePage.ets
@Entry
@Component
struct SharePage {build() {Column() {TransitionElement({ imgFit: ImageFit.Cover }).sharedTransition(SHARE_TRANSITION_ID, {duration: SHARE_ITEM_DURATION,curve: Curve.Smooth,delay: SHARE_ITEM_ANIMATION_DELAY})}}
}

说明: 两个页面的组件配置为同一个id,则转场过程中会执行共享元素转场,配置为空字符串时不会有共享元素转场效果。

总结

您已经完成了本次Codelab的学习,并了解到以下知识点:

  1. 如何实现页面间转场动画。
  2. 如何实现组件内转场动画。
  3. 如何实现共享元素转场动画。

为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→《HarmonyOS教学视频

HarmonyOS教学视频:语法ArkTS、TypeScript、ArkUI等.....视频教程

鸿蒙生态应用开发白皮书V2.0PDF:

获取完整版白皮书方式请点击→《鸿蒙生态应用开发白皮书V2.0PDF》

鸿蒙 (Harmony OS)开发学习手册

一、入门必看

  1. 应用开发导读(ArkTS)
  2. ……

二、HarmonyOS 概念

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全
  5. ........

三、如何快速入门?《做鸿蒙应用开发到底学习些啥?》

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

四、开发基础知识

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

五、基于ArkTS 开发

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册

这篇关于HarmonyOS实战开发-如何实现页面间转场动画的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/859465

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景