纯血鸿蒙APP实战开发——一镜到底“页面转场”动画

介绍

本方案做的是页面点击卡片跳转到详情预览的转场动画效果

效果图预览

使用说明

点击首页卡片跳转到详情页,再点击进入路由页面按钮,进入新的路由页面

实现思路

首页使用了一种视觉上看起来像是组件的转场动画,这种转场动画通常是通过组件的动态加载和切换来实现的,不是路由页面转场动画。

实现方案如下:

1、入场动画:采用stack布局,容器内有瀑布流卡片列表CardList和卡片详情页DetailPage(展开时是详情页,未展开是卡片组件)

  build() {
    Stack() {
      this.CardList();
      this.DetailPage();
    }
  }

2、入场动画:点击卡片后,记录当前被点击卡片在数组中的索引,DetailPage渲染被点击卡片组件,使用onAreaChange存储每个Card被点击时的位置、宽高信息,用于设置返回动画卡片组件的结束状态位置尺寸信息;

  LazyForEach(this.dataSource, (item: CardData, index) => {
    FlowItem() {
      CardPage({cardData: item})
        .onClick(() => {
          this.clickedCardIndex = index;
        })
    }
    .onAreaChange((oldValue, newValue) => {
      this.dataSource.getData(index).cardArea = newValue;
    })
    .width('100%')
  })

3、入场动画:onCardReadyExpand回调在DetailPage内部Image渲染结束时触发;(用于解决 Image 组件的渲染期间就发生页面转场导致的白色闪屏问题)
使用Stack布局,动态设置DetailPage zIndex值大于CardList,使DetailPage覆盖到CardList上;
设置expandCardId为被点击的卡片Id,触发DetailPage卡片组件-> DetailPage详情页的属性动画;(显式动画改变宽高)

  CardPage({
    cardData: this.dataSource.getData(this.clickedCardIndex),
    expandCardId: this.expandCardId,
    onCardReadyExpand: () => {
      if (!this.isDetailPageShow) {
        animateTo({duration: 5,onFinish: ()=>{
          this.expandCardId = this.dataSource.getData(this.clickedCardIndex).id;
        }}, ()=> { 
          this.isDetailPageShow = true
        })
      }
    },
    onBack: () => {
      this.expandCardId = -1;
    },
    onAnimationFinish: () => {
      if (this.expandCardId < 0) {
          this.clickedCardIndex = -1;
          this.isDetailPageShow = false;
      }
    }
  })
  .width(this.expandCardId > -1 ? '100%' : this.dataSource.getData(this.clickedCardIndex).cardArea.width)
  .height(this.expandCardId > -1 ? px2vp( this.currentDisplayHeight as number) : this.dataSource.getData(this.clickedCardIndex).cardArea.height)
  .position({
    x: this.expandCardId > -1 ? 0 : this.dataSource.getData(this.clickedCardIndex).cardArea.position.x,
    y: this.expandCardId > -1 ? 0 : (this.dataSource.getData(this.clickedCardIndex).cardArea.position.y)
  })
  .animation({duration: 200})
  .backgroundColor(Color.White)

  .zIndex(this.isDetailPageShow ? 2 : 0)

4、入场动画:CardPage内部监听expandCardId值变化,触发expandCardId相关的显式动画,透明度动画控制卡片组件和卡片详情页不共用组件的显隐

    @Prop @Watch('onExpandCardIdChange') expandCardId?: number = -1;
    onExpandCardIdChange() {
      animateTo({duration:200, onFinish: this.onAnimationFinish}, ()=>{
        this.isCardExpand = this.expandCardId === this.cardData.id
      })
    }

5、出场动画:点击返回按钮,触发重置为this.expandCardId = -1,卡片组件宽高动画和卡片组件和卡片详情页不共用组件的显隐动画,都关联expandCardId属性。即可实现出场动画。

6、一镜到底实际上是在动画开始前将UI显示相同的A组件覆盖到B卡片组件上,入场动画和出场动画作用A一个组件上。

高性能知识点

本示例使用了LazyForEach进行数据懒加载以降低内存占用。

工程结构&模块类型

  transitionanimation             // har包
     |---model
     |   |---CardData.ets          // 卡片页面的model层数据结构
     |   |---WaterFlowDataSource.ets    // 瀑布流列表 model 数据层      
     |---pages
     |   |---TransitionAnimationPage.ets           // 转场动画效果实现页面
     |   |---CardPage.ets                            // 卡片和卡片详情页面
     |   |---NewNavPage.ets                        // 从卡片详情页面使用路由跳转到的页面

模块依赖

routermodule

参考资料

动画

鸿蒙全栈开发全新学习指南

也为了积极培养鸿蒙生态人才,让大家都能学习到鸿蒙开发最新的技术,针对一些在职人员、0基础小白、应届生/计算机专业、鸿蒙爱好者等人群,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线【包含了大厂APP实战项目开发】

本路线共分为四个阶段:

第一阶段:鸿蒙初中级开发必备技能

第二阶段:鸿蒙南北双向高工技能基础:gitee.com/MNxiaona/733GH

第三阶段:应用开发中高级就业技术

第四阶段:全网首发-工业级南向设备开发就业技术:https://gitee.com/MNxiaona/733GH

《鸿蒙 (Harmony OS)开发学习手册》(共计892页)

如何快速入门?

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

开发基础知识:gitee.com/MNxiaona/733GH

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.……

鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH

鸿蒙入门教学视频:

美团APP实战开发教学:gitee.com/MNxiaona/733GH

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:gitee.com/MNxiaona/733GH

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/612265.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

opencv绘制灰度直方图-------c++

灰度直方图 cv::Mat opencvTool::calculateHistogram(const cv::Mat& image) {// 如果输入图像尚未处于灰度级&#xff0c;请将其转换为灰度级cv::Mat grayscale_image;if (image.channels() > 1){cv::cvtColor(image, grayscale_image, cv::COLOR_BGR2GRAY);}else{gra…

求一个B站屏蔽竖屏视频的脚本

求一个B站屏蔽竖屏视频的脚本 现在B站竖屏竖屏越来越多了&#xff0c;手机还好点给我一个按钮&#xff0c;选择不喜欢&#xff0c;但是我一般都用网页版看视屏&#xff0c;网页版不给我选择不喜欢的按钮&#xff0c;目测大概1/4到1/3的视频都是竖屏视频。 目前网页版唯一的进…

使用AudioCraft(MusicGen)生成音乐

AudioCraft 是一个 PyTorch 库,用于音频生成的深度学习研究。AudioCraft 包含 AudioGen 和 MusicGen 两个最先进的人工智能生成模型的推理和训练代码,用于生成高质量的音频。 MusicGen 是一种简单可控的音乐生成模型,它使用Meta 20K 小时的授权音乐来进行训练,能够生成与文…

SM4在线解密工具(支持GCM模式)

SM4在线解密工具(支持GCM模式)

spring boot参数验证注解@NotNull、@NotBlank和@NotEmpty区别

目录 前言说明举例 前言 使用spring boot参数验证是常常会使用NotNull、NotBlank和NotEmpty三个判断是否不为空的注解&#xff0c;中文都有不能为空的意思&#xff0c;大部分使用者都傻傻分清它们之间到底有什么区别。今天就让咱们来一起探索它们之间的不同吧。 说明 注解名…

rngd: Error writing /dev/tpm0

检查数据库时发现messages中一直有rngd报错&#xff0c;rngd一直未配置&#xff0c;直接关闭了 /var/log/messages-20240414:Apr 11 04:59:49 hydb2 rngd: Error writing /dev/tpm0 /var/log/messages-20240414:Apr 12 07:31:39 hydb2 rngd: Error writing /dev/tpm0 /var/log…

深度学习之前馈神经网络

1.导入常用工具包 #在终端中输入以下命令就可以安装工具包 pip install numpy pip install pandas Pip install matplotlib注&#xff1a; numpy是科学计算基础包 pandas能方便处理结构化数据和函数 matplotlib主要用于绘制图表。 #导包的代码&#xff1a; import numpy as n…

怎样的跨网软件,可以实现网间数据的安全收发?

网络隔离已是较为常见的网络安全保护措施&#xff0c;比如防火墙、网闸、VLAN&#xff0c;云桌面虚拟环境等方面进行隔离。像一些科技研发型企业&#xff0c;不仅仅是内外网隔离&#xff0c;甚至还划分办公网、研发网、测试网、生产网等&#xff0c;防止研发资料、设计资料等敏…

【机器学习300问】85、Adam梯度下降优化算法的原理是什么?

Adam优化算法取了两个算法名称的首字母——Adaptive Moment Estimation的缩写&#xff0c;结合了Momentum算法和RMSprop算法的优点。在Momentum中&#xff0c;会计算前一时刻的梯度&#xff0c;并将其用于当前时刻的梯度更新&#xff1b;而RMSprop会对梯度的大小进行自适应调整…

二叉树的遍历(前序 中序 后序)

一、前序遍历 顺序为&#xff1a; 根-->左子树---->右子树 先访问根节点&#xff0c;再递归进入根节点的左子树&#xff08;通过递归不断往下遍历&#xff09;&#xff0c;直到访问的节点没有左子树&#xff0c;此时递归进入其右子树&#xff08;通过递归进行相同操作&a…

vue布局设置——使用 el-drawer 打造个性化 Admin 后台布局设置

在前端开发中&#xff0c;我们常常需要为 admin 后台构建灵活且个性化的布局设置。今天&#xff0c;我要分享的是如何利用 el-drawer 来实现这样一个有趣的功能。 首先&#xff0c;我们来看一下主要的设置参数&#xff1a; 1. theme: 用于定义主题&#xff0c;可以根据需求切换…

Java入门基础学习笔记15——强制类型转换

大范围类型的变量是否可以赋值给小范围类型的变量呢&#xff1f; IDEA直接报错。直接报错&#xff0c;是提醒你有问题。但是我非常进行类型转换。 非要强行赋值呢&#xff1f; 强制类型转换&#xff0c;强行将类型范围大的变量&#xff0c;数据赋值给类型范围小的变量。 数据…

若依生成树表和下拉框选择树表结构(在其他页面使用该下拉框输入)

1.数据库表设计 生成树结构的主要列是id列和parent_id列&#xff0c;后者指向他的父级 2.来到前端代码生成器页面 导入你刚刚写出该格式的数据库表 3.点击编辑&#xff0c;来到字段 祖籍列表是为了好找到直接父类&#xff0c;不属于代码生成器方法&#xff0c;需要后台编…

数据挖掘(二)数据预处理

前言 基于国防科技大学 丁兆云老师的《数据挖掘》 数据挖掘 数据挖掘&#xff08;一&#xff09;数据类型与统计 2、数据预处理 2.1数据清理 缺失值处理&#xff1a; from sklearn.impute import SimpleImputer# 创建一个SimpleImputer对象&#xff0c;指定缺失值的处理策略…

day07beef-xss之根据beef-xss获取cookies

1.安装 apt-get update apt-get install beef-xss 若报错运行不了尝试 apt remove ruby apt remove beef-xss apt-get install ruby apt-get install ruby-dev libpcap-dev gem install eventmachine apt-get install beef-xss 2.运行 beef-xss 运行成功会自动弹出浏览框。 攻…

WM Transaction Code 仓库管理模块事务代码大全

1.1 LE-WM 仓库管理 Warehouse Management 仓库管理事务码 描述 LB01 Create Transfer Requirement 创建转储需求 LB02 Change transfer requirement 修改转储需求 LB03 Display Transfer Requirement 显示转储需求 LB10 TRs for Storage Type 按仓储类型的转储请求 …

一次完整的GC流程

Java堆中内存区分 Java的堆由新生代&#xff08;Young Generation&#xff09;和老年代&#xff08;Old Generation&#xff09;组成。新生代存放新分配的对象&#xff0c;老年代存放长期存在的对象。 新生代&#xff08;Young&#xff09;由年轻区&#xff08;Eden&a…

uniapp开发微信小程序,选择地理位置uni.chooseLocation

<view click"toCommunity">点击选择位置</view>toCommunity() {const that thisuni.getSetting({success: (res) > {const status res.authSetting// 如果当前设置是&#xff1a;不允许&#xff0c;则需要弹框提醒客户&#xff0c;需要前往设置页面…

linux开发笔记(buildroot 增加自己的开发板支持文件)

1、该笔记参考了mangopi r3的buildroot。某宝上卖的LC-PI-200S提供的buildroot就是这个。已经上传到我的资源中&#xff0c;可以下载看看。 2、首先在buildroot目录输入make menuconfig打开buildroot配置。 进入build options查看 可以看到第二行就是buildroot配置的保存位置…

STM32_HAL_RTC_中断实现闹钟

1STM32设置 在STM32Cude中设置RTC//具体设置看先前发的文章 再打开闹钟中断&#xff08;如下图&#xff09; 2代码思路 2.1启动闹钟&#xff08;HAL_RTC_SetAlarm_IT(&hrtc,&sAlarm,FORMAT_BCD)&#xff09; 2.2设置回调函数&#xff08;void HAL_RTC_AlarmAEventC…