纯血鸿蒙APP实战开发——首页下拉进入二楼效果案例

介绍

本示例主要介绍了利用position和onTouch来实现首页下拉进入二楼、二楼上划进入首页的效果场景,利用translate和opacity实现动效的移动和缩放,并将界面沉浸式(全屏)显示。

效果图预览

使用说明

  1. 向下滑动首页页面超过触发距离,页面进入二楼,未超过触发距离页面回弹。
  2. 二楼页面向上滑动超过触发距离,页面进入首页,未超过触发距离页面回弹。
  3. 效果图因要展示动效效果对展开速度进行了调整,可以通过SecondFloor.ets中的OFFSET_STEP和EXPAND_FLOOR_INTERVAL_TIME来调整二楼展开的速度,同理也可通过FloorView.ets中的OFFSET_STEP和EXPAND_FLOOR_INTERVAL_TIME来调整一楼展开的速度

实现思路

本例涉及的关键特性和实现方案如下:

  1. 使用Column布局将一楼页面二楼页面包裹,使用position将一、二楼页面固定,floorHeight设置二楼高度(初始Y轴为负的二楼高度),使用clip按指定的形状对当前组件进行裁剪,源码参考SecondFloor.ets和FloorView.ets。
Column() {// 二楼页面Column() {this.floorViewBuilder();}// 固定二楼刚开始位置.position({x: 0,// Y轴大小y: this.mainPageOffsetY})...// 一楼页面Column() {this.mainPageBuilder();}.position({x: 0,// Y轴大小加上二楼高度y: this.offsetY + this.floorHeight})
}
.clip(true) // TODO:知识点:按指定的形状对当前组件进行裁剪,参数为boolean类型时,设置是否按照父容器边缘轮廓进行裁剪。
  1. 通过对Column设置onTouch属性,记录手指按下和离开屏幕Y轴坐标,判断手势是上/下滑,当下滑距离达到触发距离进入二楼,未达到触发距离页面回弹(以一楼页面下滑为例),源码参考SecondFloor.ets。
Column() {...// 一楼页面Column() {this.mainPageBuilder();}...
}.onTouch((event) => {switch (event.type) {case TouchType.Down:this.onTouchDown(event);break;case TouchType.Move:this.onTouchMove(event);break;...break;}event.stopPropagation(); // 阻止冒泡})/*** 按下事件、获取按下事件的位置* @param event 触屏事件*/
private onTouchDown(event: TouchEvent) {// 获取触发按压事件Y轴的位置this.lastY = event.touches[0].windowY;...
}/*** 滑动事件* @param event 触屏事件*/
private onTouchMove(event: TouchEvent) {...let currentY = event.touches[0].windowY;// onTouch事件中本次Y轴大小减去上一次获取的Y轴大小,为负值则是向上滑动,为正值则是向下滑动let deltaY = currentY - this.lastY;...
}
  1. 使用Row布局将加载动画三个圆进行包裹,使用translate来实现圆的移动,使用scale来控制圆的加载,源码参考SecondFloor.ets。
Row() {// this.floorHeight - Math.abs(this.offsetY)为下拉距离,下拉距离超过MINI_SHOW_DISTANCE(动效最小展示距离)且小于TRIGGER_HEIGHT(触发动画高度或者动效消失高度)展示动画if ((this.floorHeight - Math.abs(this.offsetY)) > MINI_SHOW_DISTANCE && (this.floorHeight - Math.abs(this.offsetY)) <= TRIGGER_HEIGHT) {Row() {// 向左偏移圆Blank().width(this.roundSize).height(this.roundSize).borderRadius($r('app.integer.second_floor_circular_border_radius')).scale(this.immediatelyScale).backgroundColor($r('app.color.second_floor_circular_color')).translate({ x: this.animationXLeft }).opacity(((this.mFloorHeight - Math.abs(this.offsetY)) / this.mFloorHeight)) // 使用下拉距离除以二楼高度获得圆的透明度// 中心加载点Blank()...// 向右偏移圆Blank()...}}
}
  1. 操作translate来实现左右两圆实时的移动,使用scale来控制左右两圆的加载,源码参考SecondFloor.ets。
/*** 滑动事件* @param event 触屏事件*/
private onTouchMove(event: TouchEvent) {
...// TODO:知识点:确定是滑动状态后,进入动效界面,this.floorHeight减去this.offsetY的绝对值为滑动距离,在大于60(60指的是中心圆加载范围)和隐藏动效高度范围对左右圆的平移距离和和缩放进行设置if (((this.floorHeight - Math.abs(this.offsetY)) <= TRIGGER_HEIGHT) && (this.floorHeight - Math.abs(this.offsetY)) >= 60) {this.roundSize = 20;this.animationXLeft = 60;this.animationXRight = -60;// (this.floorHeight - Math.abs(this.offsetY))除以TRIGGER_HEIGHT 获取下拉百分比,使用百分比乘以60(60是根据圆最开始的位置获取)获得每次平移的距离,用来达到左右圆的X轴最后为0this.animationXLeft = this.animationXLeft - ((this.floorHeight - Math.abs(this.offsetY)) / TRIGGER_HEIGHT) * 60;this.animationXRight = this.animationXRight + ((this.floorHeight - Math.abs(this.offsetY)) / TRIGGER_HEIGHT) * 60;// 使用移动距离除以动效消失的高度,用来获取左右圆的缩放比例this.immediatelyScale = {x: ((this.floorHeight - Math.abs(this.offsetY)) / TRIGGER_HEIGHT),y: ((this.floorHeight - Math.abs(this.offsetY)) / TRIGGER_HEIGHT)};} else if (((this.floorHeight - Math.abs(this.offsetY)) < 60)) {// TODO:知识点:在中心圆加载的时候,左右圆是不显示的,因此将左右圆缩放比例大小调整为0,使用移动高度除以60(中心圆加载高度)再乘以20(圆的最终大小),以此来达到中心圆的加载效果this.roundSize = 0;this.roundSize = 20 * ((this.floorHeight - Math.abs(this.offsetY)) / 60);this.immediatelyScale = {x: 0,y: 0};} else {// 设置当二楼回收显示一楼时,三个圆属于加载成功状态this.roundSize = 20;this.immediatelyScale = { x: 1, y: 1 };this.animationXLeft = 0;this.animationXRight = 0;}...
}
  1. 在手指滑动结束离开屏幕后,通过判断此时二楼高度与Y轴高度差是否大于触发距离,若大于触发距离页面进入二楼,若小于页面进行回弹(以一楼下滑为例),源码参考SecondFloor.ets。
/*** 触摸抬起或取消触摸事件*/
private onTouchUp() {if (this.dragging) {// 二楼自身的高度减去向下Y轴的位移的绝对值大于触发值进入二楼,否则回弹if ((this.floorHeight - Math.abs(this.offsetY)) > this.expandFloorTriggerDistance) {// 进入二楼this.expandSecondFloor();} else {// 未达到触发距离回弹this.scrollByTop();}}
}

高性能知识点

本例使用了onTouch事件实时监听获取相关数据,避免在函数中进行冗余或耗时操作,例如应该减少或避免在函数打印日志,会有较大的性能损耗。

本示例使用了setInterval进行页面移动控制,在页面移动到相应的位置后使用clearInterval销毁以降低内存占用。

工程结构&模块类型

secondfloorloadanimation                     // har类型
|---model 
|   |---AppInfo.ets                          // App信息
|   |---UserInformation.ets                  // 用户信息    
|---view
|   |---SecondFloorLoadAnimation.ets         // 视图层-应用主页面
|   |---SecondFloor.ets                      // 视图层-应用一楼页面
|   |---FloorView.ets                        // 视图层-应用二楼页面

模块依赖

  • 本实例依赖common模块来实现日志的打印、资源 的调用、依赖动态路由模块来实现页面的动态加载。

参考资料

  • @ohos.window
  • 触摸事件

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

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

本路线共分为四个阶段:

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

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

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

第四阶段:全网首发-工业级南向设备开发就业技术: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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BGP学习一:关于对等体建立和状态组改变

目录 一.BGP基本概念 &#xff08;1&#xff09;.BGP即是协议也是分类 1.早期EGP 2.BGP满足不同需求 3.BGP区域间传输的优势 &#xff08;1&#xff09;安全性——只传递路由信息 &#xff08;2&#xff09;跨网段建立邻居 4.BGP总结 5.BGP的应用 &#xff08;1&#…

《动手学深度学习》V2(11-18)

文章目录 十一、二 模型选择与过拟合和欠拟合1、模型的选择2、过拟合和欠拟合3、估计模型容量4、线性分类器的VC维5、过拟合欠拟合的代码实现 :fire:①生成数据集②定义评估损失③定义训练函数④三阶多项式函数拟合⑤线性函数拟合(欠拟合)⑤高阶多项式函数拟合(过拟合) 十三、权…

docker私有仓库部署与管理

一、搭建本地公有仓库 1.1 首先下载registry镜像 docker pull registry 1.2 在daemon.json文件中添加私有镜像仓库地址并重新启动docker服务 vim /etc/docker/daemon.json 1.3 运行registry容器 docker run -itd -v /data/registry:/var/lib/registry -p 5000:5000 --restartal…

VP Codeforces Round 944 (Div 4)

感受&#xff1a; A~G 其实都不难&#xff0c;都可以试着补起来。 H看到矩阵就放弃了。 A题&#xff1a; 思路&#xff1a; 打开编译器 代码&#xff1a; #include <iostream> #include <vector> #include <algorithm> #define int long long using na…

Ansible——playbook编写

目录 环境配置 一、简介 1.什么是playbook 2.playbook组成 二、应用实例 1.基础命令 1.编写 ceshi1.yaml 文件 2.运行Playbook 2.定义、引用变量 1.编写ceshi2.yaml文件 3.指定远程主机sudo切换用户 1.编写ceshi3.yaml文件 2.修改被控主机sudoers文件 3.给zhangsa…

等保一体机能过三级等保吗?过等保无需再买安全设备如何做到?

等保一体机能过三级等保吗&#xff1f;过等保无需再买安全设备如何做到&#xff1f; 全云在线 2024-03-28 12:08 广东 尽管等保建设的标准是统一的&#xff0c;但由于不同行业和用户规模的差异&#xff0c;建设方案呈现出多样化的特点。 虽然重点行业过等保现象确实已经十分…

Unity图文混排EmojiText的使用方式和注意事项

​​​​​​​ 效果演示&#xff1a; 使用方式&#xff1a; 1、导入表情 2、设置图片格式 3、生成表情图集 4、创建/修改目标材质球 5、测试 修复换行问题 修复前&#xff1a; 修复后&#xff1a; 修复代码&#xff1a; 组件扩展 1、右键扩展 2、组件归类&#…

南京信工一班IP(2)

第六章&#xff0c;BGP—边界网关协议 自治系统—AS ​ 定义&#xff1a;由一个单一的机构或组织所管理的一系列IP网络及其设备所构成的集合。 ​ AS的来源&#xff1a; 整个网络规模过大&#xff0c;会导致路由信息收敛速度过慢&#xff0c;设备对相同目标认知不同。AS之间…

LeetCode题目104: 二叉树的最大深度(递归\迭代\层序遍历\尾递归优化\分治法实现 )

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

Android system property运作流程源码分析

一.序 前文分析了build.prop这个系统属性文件的生成&#xff0c;每个属性都有一个名称和值&#xff0c;他们都是字符串格式。属性被大量使用在Android系统中&#xff0c;用来记录系统设置或进程之间的信息交换。属性是在整个系统中全局可见的。每个进程可以get/set属性&#x…

【IMX6ULL项目】IMX6ULL下Linux实现产测工具框架

电子产品量产测试与烧写工具。这是一套软件&#xff0c;用在我们的实际生产中&#xff0c; 有如下特点&#xff1a; 1.简单易用&#xff1a; 把这套软件烧写在 SD 卡上&#xff0c;插到 IMX6ULL 板子里并启动&#xff0c;它就会自动测试各个模块、烧写 EMMC 系统。 工人只要按…

数据库系统理论——关系数据库标准语言SQL

文章目录 一、数据定义1、基本表的定义、删除与修改2、索引的建立于删除&#xff08;了解&#xff09; 二、数据查询&#xff08;会其中一种&#xff09;1、单表查询&#xff08;1&#xff09;这里出现重复元组&#xff0c;怎么处理&#xff1f;&#xff1f;&#xff08;2&…

渗透测试-信息收集

网络安全信息收集是网络安全领域中至关重要的一环&#xff0c;它涉及到对目标系统、网络或应用进行全面而细致的信息搜集和分析。这一过程不仅有助于理解目标网络的结构、配置和潜在的安全风险&#xff0c;还能为后续的渗透测试、风险评估和安全加固提供有力的支持。 在网络安…

单调栈问题

原理 单调栈的核心原理是&#xff1a;在栈内保持元素的单调性&#xff08;递增或递减&#xff09; 单调递增栈&#xff1a; 用于处理“下一个更小的元素”问题。当新元素比栈顶元素小或等于时&#xff0c;直接入栈&#xff1b;否则&#xff0c;一直从栈顶弹出元素&#xff0c…

信息系统项目管理师0102:可行性研究的内容(7项目立项管理—7.2项目可行性研究—7.2.1可行性研究的内容)

点击查看专栏目录 文章目录 7.2项目可行性研究7.2.1可行性研究的内容1.技术可行性分析2.经济可行性分析3.社会效益可行性分析4.运行环境可行性分析5.其他方面的可行性分析记忆要点总结7.2项目可行性研究 可行性研究是在项目建议书被批准后,从技术、经济、社会和人员等方面的条…

在STM32中用寄存器方式点亮流水灯

文章目录 实验资料一、对寄存器的理解1.通俗认识寄存器2.深入了解寄存器&#xff08;1&#xff09;端口配置低寄存器&#xff08;配置0到7引脚的寄存器&#xff09;&#xff08;2&#xff09;端口配置高寄存器&#xff08;配置8到15引脚&#xff09; 3.GPIO口的功能描述 二、配…

【网络】网络基础

目录 一、前言 1.计算机网络背景 2.认识协议 二、网络协议初识 1.OSI七层模型 2.TCP/IP五层(或四层)模型 3.网络传输基本流程 4.数据包封装和分用 5.网络中的地址管理 1.IP地址 2.MAC地址 一、前言 1.计算机网络背景 网络之前&#xff0c;我们所有在电脑上的操作都是…

LeetCode题练习与总结:二叉树的中序遍历--94

一、题目描述 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a;roo…

Github学习

1.Git与Github 区别: Git是一个分布式版本控制系统&#xff0c;简单的说就是一个软件&#xff0c;用于记录一个或若干个文件内容变化&#xff0c;以便将来查阅特点版本修订情况的软件。 Github是一个为用户提高Git服务的网站&#xff0c;简单说就是一个可以放代码的地方。Gi…

韩顺平0基础学Java——第10天

p202-233 类与对象&#xff08;第七章&#xff09; 成员方法 person类中的speak方法&#xff1a; 1.public表示方法是公开的 2.void表示方法没有返回值 3.speak&#xff08;&#xff09;中&#xff0c;speak表示方法名&#xff0c;括号是形参列表。 4.大括号为方法体&am…