当前位置: 首页 > news >正文

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版)合理使用动画丢帧规范实践

本文列举了部分用于优化动画时延的正反案例&#xff0c;帮助开发者在遇到相似场景时进行优化&#xff0c;解决构建页面动画时遇到动画时延较长的问题。 减少动画丢帧 在播放动画或者生成动画时&#xff0c;画面产生停滞而导致帧率过低的现象&#xff0c;称为动画丢帧。 播放…...

基于BiLSTM-CRF的医学命名实体识别研究(下)模型构建

一.生成映射字典 接下来需要将每个汉字、边界、拼音、偏旁部首等映射成向量。所以&#xff0c;我们首先需要来构造字典&#xff0c;统计多少个不同的字、边界、拼音、偏旁部首等&#xff0c;然后再构建模型将不同的汉字、拼音等映射成不同的向量。 在prepare_data.py中自定义…...

5.sklearn-朴素贝叶斯算法、决策树、随机森林

文章目录 环境配置&#xff08;必看&#xff09;头文件引用1.朴素贝叶斯算法代码运行结果优缺点 2.决策树代码运行结果决策树可视化图片优缺点 3.随机森林代码RandomForestClassifier()运行结果总结 本章学习资源 环境配置&#xff08;必看&#xff09; Anaconda-创建虚拟环境…...

VMWARE VCENTER6.7 VCSA通过Web5480进行版本升级

VCENTER当前版本如下图 操作前先给VCENTER打一个快照&#xff0c;出问题可以立即回退 1、先下载VCSA镜像&#xff0c;并将VCSA镜像上传至DataStore中&#xff1b; 2、选中VCSA虚拟机&#xff0c;编辑配置 3、挂载新上传的VCSA镜像&#xff0c;一定要勾选“已连接”和“打开电源…...

GIT使用常见问题

如何安装Git&#xff1f; 在Windows操作系统中&#xff0c;可以从Git官方网站&#xff08;https://git-scm.com&#xff09;下载最新的Git安装程序&#xff0c;然后按照提示进行安装。在Mac操作系统中&#xff0c;可以使用Homebrew或者直接从Git官方网站下载安装程序进行安装。…...

内核链表

一、特点 灵活性 内核链表可以连接各种不同类型的数据结构&#xff0c;因为它只包含指向下一个和上一个节点的指针&#xff0c;不依赖特定的数据类型&#xff0c;这使得内核开发者可以根据不同的需求灵活地使用它。你可以将不同类型的结构体通过内核链表连接起来&#xff0c;实…...

行空板上YOLO和Mediapipe视频物体检测的测试

Introduction 经过前面三篇教程帖子&#xff08;yolov8n在行空板上的运行&#xff08;中文&#xff09;&#xff0c;yolov10n在行空板上的运行&#xff08;中文&#xff09;&#xff0c;Mediapipe在行空板上的运行&#xff08;中文&#xff09;&#xff09;的介绍&#xff0c;…...

【Spring Boot 3】【Web】ProblemDetail

【Spring Boot 3】【Web】ProblemDetail 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花…...

市占率最高的显示器件,TFT_LCD的驱动系统设计--Part 1

目录 一、简介 二、TFT-LCD驱动系统概述 &#xff08;一&#xff09;系统概述 &#xff08;二&#xff09;设计要点 二、扫描驱动电路设计 &#xff08;一&#xff09;概述 扫描驱动电路的功能 扫描驱动电路的组成部分 设计挑战 驱动模式 &#xff08;二&#xff09…...

Linux基础 -- 获取CPU负载信息

Linux Kernel 获取当前负载情况 本文档介绍了如何在 Linux 内核中获取系统的负载情况。我们将从用户态程序、内核模块开发等角度展示相关方法。 1. 通过 /proc/loadavg 文件获取负载 /proc/loadavg 文件包含了系统的负载信息&#xff0c;通常包括过去 1 分钟、5 分钟和 15 分…...

Django 中的用户界面 - 创建速度计算器

在 Django 中创建一个用户界面来计算速度&#xff0c;可以通过以下步骤完成。这个速度计算器将允许用户输入距离和时间&#xff0c;计算并显示速度。 一、问题背景 一位 Django 新手希望使用 Django 构建一个用户界面&#xff0c;以便能够计算速度&#xff08;速度 距离/时间…...

spring security 如何解决跨域的

一、什么是 CORS CORS(Cross-Origin Resource Sharing) 是由 W3C制定的一种跨域资源共享技术标准&#xff0c;其目就是为了解决前端的跨域请求。在JavaEE 开发中&#xff0c;最常见的前端跨域请求解决方案是早期的JSONP&#xff0c;但是JSONP 只支持 GET 请求&#xff0c;这是一…...

日志系统前置知识

日志&#xff1a;程序运行过程中所记录的程序运行状态信息。通过这些信息&#xff0c;以便于程序员能够随时根据状态信息&#xff0c;对系统的运行状态进行分析。功能&#xff1a;能够让用户非常简便的进行日志的输出以及控制。 同步写日志 同步日志是指当输出日志时&#xff…...

【Spring Boot 3】【Web】全局异常处理

【Spring Boot 3】【Web】全局异常处理 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费…...

Dcoker 运行es

1&#xff0c;创建network docker network create my-network 2&#xff0c;docker运行es容器 docker run -d --name es-container --net my-network -p 9200:9200 -p 9300:9300 -e "discovery.typesingle-node" docker.elastic.co/elasticsearch/elasticsearch:7…...

7系列FPGA HR/HP I/O区别

HR High Range I/O with support for I/O voltage from 1.2V to 3.3V. HP High Performance I/O with support for I/O voltage from 1.2V to 1.8V. UG865&#xff1a;Zynq-7000 All Programmable SoC Packaging and Pinout...

sqli-labs靶场通关攻略(五十一到六十关)

sqli-labs-master靶场第五十一关 步骤一&#xff0c;尝试输入?sort1 我们发现这关可以报错注入 步骤二&#xff0c;爆库名 ?sort1 and updatexml(1,concat(0x7e,database(),0x7e),1)-- 步骤三&#xff0c;爆表名 ?sort1 and updatexml(1,concat(0x7e,(select group_conc…...

c语言中的动态内存管理

在 C 语言中&#xff0c;动态内存管理主要通过以下几个函数实现&#xff1a; 一、malloc 函数 功能&#xff1a; malloc 函数用于在内存的动态存储区中分配一块长度为 size 字节的连续区域。函数返回一个指向分配区域起始地址的指针&#xff0c;如果分配失败则回 NULL 示例: …...

生信机器学习入门4 - scikit-learn训练逻辑回归(LR)模型和支持向量机(SVM)模型

通过逻辑回归&#xff08;logistic regression&#xff09;建立分类模型 1.1 逻辑回归可视化和条件概率 激活函数 (activation function)&#xff1a; 一种函数&#xff08;如 ReLU 或 S 型函数&#xff09;&#xff0c;用于对上一层的所有输入进行求加权和&#xff0c;然后生…...

COD论文笔记 Adaptive Guidance Learning for Camouflaged Object Detection

论文的主要动机、现有方法的不足、拟解决的问题、主要贡献和创新点如下&#xff1a; 动机&#xff1a; 论文的核心动机是解决伪装目标检测&#xff08;COD&#xff09;中的挑战性任务。伪装目标检测旨在识别和分割那些在视觉上与周围环境高度相似的目标&#xff0c;这对于计算…...

.NET源码生成器基于partial范式开发和nuget打包塘

1 安装与初始化 # 全局安装 OpenSpec npm install -g fission-ai/openspeclatest # 在项目目录下初始化 cd /path/to/your-project openspec init 初始化时&#xff0c;OpenSpec 会提示你选择使用的 AI 工具&#xff08;Claude Code、Cursor、Trae、Qoder 等&#xff09;。 3 O…...

Linux 文件权限 rwxrwxr-- 完整解析

&#x1f4cc; Linux 文件权限 rwxrwxr-- 完整解析这是 Linux 系统中文件 / 目录权限的符号表示法&#xff0c;下方的 7 6 4 是对应的八进制数字权限&#xff0c;我们一步步拆解&#xff1a;1. 权限结构与含义Linux 权限分为 3 组&#xff0c;每组 3 位&#xff0c;对应 3 类用…...

Bebas Neue:为什么这个开源字体能成为设计师的秘密武器?

Bebas Neue&#xff1a;为什么这个开源字体能成为设计师的秘密武器&#xff1f; 【免费下载链接】Bebas-Neue Bebas Neue font 项目地址: https://gitcode.com/gh_mirrors/be/Bebas-Neue 你是不是经常在设计标题时感到纠结&#xff1f;想要一种既现代又有冲击力的字体&a…...

ABAP RFC SQL 模糊查询与动态区间条件实战解析

1. ABAP RFC接口中的模糊查询实战技巧 在SAP系统开发中&#xff0c;RFC&#xff08;Remote Function Call&#xff09;接口是实现跨系统数据交互的核心技术。当外部系统需要从SAP获取数据时&#xff0c;模糊查询功能往往成为刚需。不同于选择屏幕的便捷操作&#xff0c;RFC接口…...

命名空间自动推导、嵌套别名、跨文件作用域优化,PHP 8.9这3项增强将淘汰PSR-4自动加载器?

第一章&#xff1a;PHP 8.9命名空间增强的演进背景与设计哲学PHP 命名空间自 5.3 版本引入以来&#xff0c;已成为组织大型代码库的核心机制。然而&#xff0c;随着现代 PHP 应用向模块化、跨包协作和类型安全深度演进&#xff0c;传统命名空间在语义表达力、跨作用域引用效率及…...

【2026年最新600套毕设项目分享】基于Spring Boot的音乐播放网站(14348)

有需要的同学&#xff0c;源代码和配套文档领取&#xff0c;加文章最下方的名片哦二、资料介绍完整源代码&#xff08;前后端源代码SQL脚本&#xff09;配套文档&#xff08;LWPPT开题报告/任务书&#xff09;远程调试控屏包运行一键启动项目&#xff08;无需搭建环境&#xff…...

3分钟搞定:IDM无限试用重置工具完整使用指南

3分钟搞定&#xff1a;IDM无限试用重置工具完整使用指南 【免费下载链接】idm-trial-reset Use IDM forever without cracking 项目地址: https://gitcode.com/gh_mirrors/id/idm-trial-reset 你是否曾因Internet Download Manager&#xff08;IDM&#xff09;试用期结束…...

Spring框架中多TaskExecutor Bean冲突的自动注入问题及解决方案

1. 当Spring遇到多个TaskExecutor时的烦恼 最近在重构一个老项目时&#xff0c;我遇到了一个典型的Spring自动注入问题。项目启动时突然报错&#xff0c;控制台赫然显示"NoUniqueBeanDefinitionException: expected single matching bean but found 3"。仔细一看&…...

恒模约束波形设计(Constant Modulus Waveform Design)第2章 MIMO雷达波形设计基础

目录 2.1 MIMO雷达系统模型 2.1.1 发射-接收信号模型与阵列几何配置 2.1.2 信号依赖干扰建模 2.1.3 扩展目标与点目标检测模型 2.2 波形设计目标函数 2.2.1 波束赋形设计准则 2.2.2 输出SINR最大化框架 2.2.3 CRLB最小化方法 2.3 硬件约束与工程实现 2.3.1 高功率放大…...

高效获取城通网盘直链:智能解析工具使用指南

高效获取城通网盘直链&#xff1a;智能解析工具使用指南 【免费下载链接】ctfileGet 获取城通网盘一次性直连地址 项目地址: https://gitcode.com/gh_mirrors/ct/ctfileGet 还在为城通网盘的下载限制而烦恼吗&#xff1f;ctfileGet是一款专为突破城通网盘下载限制而设计…...