HarmonyOS开发实战( Beta5版)合理使用动画丢帧规范实践

2024-09-05 07:12

本文主要是介绍HarmonyOS开发实战( Beta5版)合理使用动画丢帧规范实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文列举了部分用于优化动画时延的正反案例,帮助开发者在遇到相似场景时进行优化,解决构建页面动画时遇到动画时延较长的问题。

减少动画丢帧

在播放动画或者生成动画时,画面产生停滞而导致帧率过低的现象,称为动画丢帧。

播放动画时,系统需要在一个刷新周期内完成动画变化曲线的计算,完成组件布局绘制等操作。建议使用系统提供的动画接口,只需设置曲线类型、终点位置、时长等信息,就能够满足常用的动画功能,减少UI主线程的负载。

反例:应用使用了自定义动画,动画曲线计算过程很容易引起UI线程高负载,易导致丢帧。

@Entry
@Component
struct AttrAnimationExample0 {@State widthSize: number = 200@State heightSize: number = 100@State flag: boolean = truecomputeSize() {let duration = 2000let period = 16let widthSizeEnd = 0let heightSizeEnd = 0if (this.flag) {widthSizeEnd = 100heightSizeEnd = 50} else {widthSizeEnd = 200heightSizeEnd = 100}let doTimes = duration / periodlet deltaHeight = (heightSizeEnd - this.heightSize) / doTimeslet deltaWeight = (widthSizeEnd - this.widthSize) / doTimesfor (let i = 1; i <= doTimes; i++) {let t = period * (i);setTimeout(() => {this.heightSize = this.heightSize + deltaHeightthis.widthSize = this.widthSize + deltaWeight}, t)}this.flag = !this.flag}build() {Column() {Button('click me').onClick(() => {let delay = 500setTimeout(() => { this.computeSize() }, delay)}).width(this.widthSize).height(this.heightSize).backgroundColor(0x317aff)}.width('100%').margin({ top: 5 })}
}

img

使用系统提供的属性动效API

建议:通过系统提供的属性动效API实现上述动效功能。

@Entry
@Component
struct AttrAnimationExample1 {@State widthSize: number = 200@State heightSize: number = 100@State flag: boolean = truebuild() {Column() {Button('click me').onClick((event?: ClickEvent | undefined) => {if (this.flag) {this.widthSize = 100this.heightSize = 50} else {this.widthSize = 200this.heightSize = 100}this.flag = !this.flag}).width(this.widthSize).height(this.heightSize).backgroundColor(0x317aff).animation({duration: 2000, // 动画时长curve: Curve.Linear, // 动画曲线delay: 500, // 动画延迟iterations: 1, // 播放次数playMode: PlayMode.Normal // 动画模式}) // 对Button组件的宽高属性进行动画配置}.width('100%').margin({ top: 5 })}
}

img

更详细的API文档请参考:属性动画。

使用系统提供的显式动效API

建议:通过系统提供的显式动效API实现上述动效功能。

@Entry
@Component
struct AnimateToExample2 {@State widthSize: number = 200;@State heightSize: number = 100;@State flag: boolean = true;build() {Column() {Button('click me').onClick((event?: ClickEvent | undefined) => {if (this.flag) {animateTo({duration: 2000, // 动画时长curve: Curve.Linear, // 动画曲线delay: 500, // 动画延迟iterations: 1, // 播放次数playMode: PlayMode.Normal // 动画模式}, () => {this.widthSize = 100;this.heightSize = 50;})} else {animateTo({duration: 2000, // 动画时长curve: Curve.Linear, // 动画曲线delay: 500, // 动画延迟iterations: 1, // 播放次数playMode: PlayMode.Normal // 动画模式}, () => {this.widthSize = 200;this.heightSize = 100;})}this.flag = !this.flag;}).width(this.widthSize).height(this.heightSize).backgroundColor(0x317aff)}.width('100%').margin({ top: 5 })}
}

img

更详细的API文档请参考:显式动画。

优化效果

相比于自定义动画,使用系统提供的动效API可提高动画帧数,提高应用性能。

动画实现方式帧数(fps)
自定义动画60
属性动效API120
显式动效API120

合理设置隐式动画

Tabs组件在不为BottomTabBarStyle样式时,切换页面时默认加载300ms的隐式动画,如果开发场景不需要该动画效果,会因默认加载导致页面跳转完成时延变长,此时可手动设置animationDuration减少动画完成时延。下述正反示例分别为100ms和1000ms的动画时延:

反例:

@Entry
@Component
struct TabsExample {...private controller: TabsController = new TabsController();build() {Column() {Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {TabContent()TabContent()// ...}// ...// 设置Tabs页面跳转的动画时长为1000ms.animationDuration(1000)}.width('100%')}
}

img

正例:

@Entry
@Component
struct TabsExample {...private controller: TabsController = new TabsController();build() {Column() {Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {TabContent()TabContent()// ...}// ...// 设置Tabs页面跳转的动画时长为100ms.animationDuration(100)}.width('100%')}
}

img

优化效果

优化前 1000ms优化后 100ms

img

img

上述示例通过减少animationDuration数值,减少Tabs切换完成时延。当数值设置为0且TabBar不为BottomTabBarStyle样式时,隐式动效延时为默认的300ms。开发者可根据实际场景适当减少隐式动效时延,如果应用没有特殊的动效要求时,建议设置数值为1,减少阻塞主线程,提高应用性能。

更详细的API文档请参考:Tabs-animationduration。

合理设置动效时长

滚动类组件可使用fling方法按传入的初始速度进行惯性滚动,不合理的滚动速度设置可能导致动效时长过长,此时应通过加快滚动速度减少动效时长。下述正反示例通过改变List组件惯性滚动速度减少动效时长:

反例:

@Entry
@Component
struct ListExample {scrollerForList: Scroller = new Scroller();build() {Column() {Button('Fling100').onClick(() => {// 设置当前滚动初始速度为100vp/sthis.scrollerForList.fling(100);})List({ space: 20, initialIndex: 0, scroller: this.scrollerForList }) {// ...}}}
}

正例:

@Entry
@Component
struct ListExample {scrollerForList: Scroller = new Scroller();build() {Column() {Button('Fling100').onClick(() => {// 设置当前滚动初始速度为10000vp/sthis.scrollerForList.fling(10000);})List({ space: 20, initialIndex: 0, scroller: this.scrollerForList }) {// ...}}}
}

优化效果

100vp/s:

img

10000vp/s:

img

示例动效耗时(ms)
优化前392
优化后200

上述示例在提高滚动速度到10000vp/s后,相比100vp/s减少了200ms的动画时延。开发者可根据实际场景适当增加滚动速度,在不影响页面效果的情况下减少页面完成时延,提高应用性能。

最后

小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,不同的角度的问了一些问题,我明显感觉到一点,那就是许多人参与鸿蒙开发,但是又不知道从哪里下手,因为资料太多,太杂,教授的人也多,无从选择。有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)文档用来跟着学习是非常有必要的。 

为了确保高效学习,建议规划清晰的学习路线,涵盖以下关键阶段:

GitCode - 全球开发者的开源社区,开源代码托管平台  希望这一份鸿蒙学习文档能够给大家带来帮助~


鸿蒙(HarmonyOS NEXT)最新学习路线

该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案

路线图适合人群:

IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术

2.视频学习教程+学习PDF文档

HarmonyOS Next 最新全套视频教程

  纯血版鸿蒙全套学习文档(面试、文档、全套视频等)       

​​

总结

参与鸿蒙开发,你要先认清适合你的方向,如果是想从事鸿蒙应用开发方向的话,可以参考本文的学习路径,简单来说就是:为了确保高效学习,建议规划清晰的学习路线

这篇关于HarmonyOS开发实战( Beta5版)合理使用动画丢帧规范实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Golang操作DuckDB实战案例分享

《Golang操作DuckDB实战案例分享》DuckDB是一个嵌入式SQL数据库引擎,它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的,DuckDB支持各种数据类型和SQL特性... 目录DuckDB的主要优点环境准备初始化表和数据查询单行或多行错误处理和事务完整代码最后总结Duck

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

使用SQL语言查询多个Excel表格的操作方法

《使用SQL语言查询多个Excel表格的操作方法》本文介绍了如何使用SQL语言查询多个Excel表格,通过将所有Excel表格放入一个.xlsx文件中,并使用pandas和pandasql库进行读取和... 目录如何用SQL语言查询多个Excel表格如何使用sql查询excel内容1. 简介2. 实现思路3