HarmonyOS NEXT 网格元素交换案例

网格元素交换案例

介绍

直接进行交换和删除元素会给用户带来不好的体验效果,因此需要在此过程中注入一些特色的动画来提升体验效果,本案例通过Grid组件、attributeModifier、以
及animateTo函数实现了拖拽动画和删除动画。

效果图预览

使用说明

  1. 进入页面,点击编辑,长按网格元素,执行拖拽操作,拖拽过程中显示此网格元素,拖拽到一定的位置时,会进行网格元素的位置交换。
  2. 编辑模式下,点击网格元素,此元素会被删除。

实现思路

本示例主要通过attributeModifier、supportAnimation、animateTo等实现了删除动画以及长按拖拽动画。attributeModifier绑定自定义属性对象,
控制每个网格元素的属性更新。执行删除操作时,通过animateTo去更新offset值以及opacity等属性。supportAnimation设置为true,支持GridItem
拖拽动画,在onItemDragStart开始拖拽网格元素时触发,onItemDragStart可以返回一个@Builder修饰的自定义组件,这样在拖拽的时候,
能够显示目标元素。onItemDrop在网格元素内停止拖拽时触发。此时执行元素位置的切换功能。

  1. 声明一个数组,添加自定义属性对象,每个自定义属性对象对应一个网格元素,源码参考AttributeModifier.ets和GridItemDeletionCtrl.ets。
 constructor(data: T[]) {
   this.gridData = data;
   data.forEach(() => {
     this.modifier.push(new GridItemModifier());
   })
 }
 /**
 * 声明GridItem动态属性
 */
@Observed
export class GridItemModifier implements AttributeModifier<GridItemAttribute> {
  public offsetX: number = 0;
  public offsetY: number = 0;
  public opacity: number = 1;

  /**
   * 定义组件普通状态时的样式
   * @param instance
   */
  applyNormalAttribute(instance: GridItemAttribute): void {
    instance.translate({ x: this.offsetX, y: this.offsetY });
    instance.opacity(this.opacity);
  }
}
  1. 绑定attributeModifier属性,attributeModifier属性的值为对应的自定义属性对象。源码参考GridExchange.ets。
 GridItem() {
   IconWithNameView({ app: item })
 }
 .onAreaChange((oldValue: Area, newValue: Area) => {
   this.itemAreaWidth = Number(newValue.width);
 })
 .onTouch((event: TouchEvent) => {
   if (event.type === TouchType.Down) {
     this.movedItem = this.appInfoList[index];
   }
 })
 // TODO:知识点:动态绑定属性信息
 .attributeModifier(this.GridItemDeletion.getModifier(item) ? this.GridItemDeletion.getModifier(item) : undefined)
  1. 编辑模式下点击网格元素,执行删除操作,删除过程中使用animateTo来更新元素的偏移量并实现动画效果。源码参考GridItemDeletionCtrl.ets。
 deleteGridItem(item: T, itemAreaWidth: number): void {
   const index: number = this.gridData.indexOf(item);
   // 最后一条数据不执行偏移
   if (index === this.gridData.length - 1) {
     this.gridData.splice(index, 1);
     this.modifier.splice(index, 1);
     return;
   }
   // TODO:知识点:实现删除动画。先让目标元素的opacity为0,不可视,直接删除目标元素会导致偏移的时候位置异常,接着遍历元素的属性对象,修改偏移量。
   this.modifier[index].opacity = 0;
   animateTo({
     curve: Curve.Friction, duration: ANIMATION_DURATION, onFinish: () => {
       // 初始化偏移位置
       this.modifier.forEach((item) => {
         item.offsetX = 0;
         item.offsetY = 0;
       })
       // 删除对应的数据
       this.gridData.splice(index, 1);
       this.modifier.splice(index, 1);
       this.status = DeletionStatus.FINISH;
     }
   }, () => {
     this.modifier.forEach((item: GridItemModifier, ind: number) => {
       if (ind > index && ind % COLUMN_COUNT !== 0) {
         item.offsetX = -itemAreaWidth;
       } else if (ind > index && ind % COLUMN_COUNT === 0) {
         item.offsetX = itemAreaWidth * 4; // 位置偏移到上一行的最后一列,因此偏移4个gridItem所占的宽度
         item.offsetY = -GRID_ITEM_HEIGHT;
       }
     })
     this.status = DeletionStatus.START;
   })
 }
  1. 交换网格元素,onItemDragStart以及onItemDrop来完成元素的交换功能,supportAnimation设置为true,支持在拖拽时显示动画效果。onItemDragStart函数中
    返回目标自定义组件,可以在拖拽过程中显示。onItemDrop函数执行最后网格元素的交换。 源码参考GridExchange.ets。
 .supportAnimation(true)
 .editMode(this.isEdit)
 .onItemDragStart((event: ItemDragInfo, itemIndex: number) => {
   // TODO:知识点:在onItemDragStart函数返回自定义组件,可在拖拽过程中显示此自定义组件。
   return this.pixelMapBuilder();
 })
 .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => {
   // TODO:知识点:执行gridItem切换操作
   if (isSuccess && insertIndex < this.appInfoList.length) {
     this.changeIndex(itemIndex, insertIndex);
   }
 })

高性能知识点

  • 动态加载数据场景可以使用LazyForEach遍历数据。
  • onAreaChange
    在区域发生大小变化的时候会进行调用,由于删除操作或者网格元素的交互都能够触发区域函数的使用,操作频繁,
    建议此处减少日志的打印、复用函数逻辑来降低性能的内耗。
  • onTouch
    在进行手势操作的时候会进行多次调用,建议此处减少日志的打印、复用函数逻辑来降低性能的内耗。

工程结构&模块类型

gridexchange                                 // har类型
|---model
|   |---AppInfo.ets                          // App信息
|   |---AttributeModifier.ets                // 属性对象
|   |---GridItemDeletionCtrl.ets             // 列表项交换
|   |---MockData.ets                         // 模拟数据
|---view
|   |---GridExchange.ets                     // 视图层-应用主页面

模块依赖

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

参考资料

Grid

animateTo

attributeModifier

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

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

开发基础知识:https://qr21.cn/FV7h05

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

基于ArkTS 开发:https://qr21.cn/FV7h05

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

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

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

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

相关文章

【网络】Burpsuite学习笔记

文章目录 1.介绍1.1 正常客户端与服务端通信&BurpSuite代理后1.2 下载激活参考地址1.3 代理设置1.4 Proxy SwitchyOmega 使用1.4.1 新建情景模式1.4.2 设置代理1.4.2 应用选项 1.5 FoxyProxy 使用1.6 安装证书1.6.1 方式一1.6.2 方式二1.6.3 浏览器安装证书1.6.4 或者直接双…

基于改进遗传算法的配电网故障定位(matlab代码)

1 主要内容 该程序复现文章《基于改进遗传算法的配电网故障定位》&#xff0c;将改进的遗传算法应用于配电网故障定位中, 并引入分级处理思想, 利用配电网呈辐射状的特点, 首先把整个配电网划分为主干支路和若干独立区域, 再利用该算法分别对各独立区域进行故障定位, 然后进行…

独立开源版:零点城市社交电商v2.1.2.4

源码介绍 独立版&#xff1a;零点城市社交电商v2.1.2.4 新增首页新增多弹窗 注意&#xff1a;如果没有此完整程序勿下载 全开源解密版代码&#xff0c;后端完全开源&#xff0c;前端是VUE前端&#xff0c;可自行二开自己想要的功能。 独立版零点城市社交电商 小程序致力于…

tcp bbr pacing 的对与错

前面提到 pacing 替代 burst 是大势所趋&#xff0c;核心原因就是摩尔定律逐渐失效&#xff0c;主机带宽追平交换带宽&#xff0c;交换机不再能轻易吸收掉主机突发&#xff0c;且随着视频类流量激增&#xff0c;又不能以大 buffer 做带宽后备。因此&#xff0c;主机必须 pacing…

CentOS的简单介绍及常用命令

1、CentOS 的简单介绍&#xff1a; CentOS是Community Enterprise Operating System的缩写&#xff0c;也叫做社区企业操作系统。是企业Linux发行版领头羊Red Hat Enterprise Linux&#xff08;以下称之为RHEL&#xff09;的再编译版本&#xff08;是一个再发行版本&#xff09…

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第五套

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第五套 (共9套&#xff0c;有答案和解析&#xff0c;答案非官方&#xff0c;仅供参考&#xff09;&#xff08;共九套&#xff0c;每套四十个选择题&#xff09; 部分题目分享&#xff0c;完整版获取&#xff08;WX:didadida…

gazebo中vins-fusion在仿真小车上的部署

软件要求&#xff1a;Ubuntu 20.04 ros的noetic版本&#xff0c;我是在虚拟机vitrualbox上运行的 这几天在学ROS&#xff0c;跟着赵虚左老师过了一遍之后&#xff0c;感觉还是有很多不懂的地方&#xff0c;xtdrone上仿真跟着文档走了一遍&#xff0c;好像没学到什么东西&#…

【华为笔试题汇总】2024-04-17-华为春招笔试题-三语言题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是KK爱Coding &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为近期的春秋招笔试题汇总&#xff5e; &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f…

【计算机考研】考408,还是不考408,性价比高❓

最近刷了很多帖子都偏向408太难了不要报考 但我的看法是408是计算机的考研趋势&#xff0c;并且择校的选择更多&#xff0c;408只是科目更广泛&#xff0c;与自命题相比其实各有各的难度 如果觉得自己数学基础不太好&#xff0c;时间不太够的同学可以了解一下自命题&#xff…

nodejs模块机制

模块机制 CommonJs规范 模块引用 上下文提供require()方法来引人外部模块var math require(math) 模块定义 exports 对象用于到处当前模块中的方法和变量module代表模块自身 exports.add function() {...}在另一个模块中使用require()方法进行导入。就可以使用 区别和联系 …

电力系统卫星授时信号安全隔离装置防护方案

电力系统是国家关键基础设施&#xff0c; 电力安全关系国计民生&#xff0c; 是国家安全的重要保障&#xff0c; 与政治安全、经济安全、 网络安全、社会安全等诸多领域密切关联。电网运行情况瞬息万变&#xff0c;为了在其发生事故时能够及时得到处理&#xff0c;需要统一的时…

Redis中的事务(二)

事务 一个完整的WATCH事务执行过程 假设当前服务端为c10086&#xff0c;而数据库watched_keys字典的当前状态如图所示&#xff0c;那么当c10086执行以下WATCH命令之后 c10086> WATCH "name" OKwatched_keys字典将更新如图所示的状态。接下来客户端c10086继续向…

[2021最新]Java时间戳和日期时间互转换

代码&#xff1a; import java.text.ParseException; import java.text.SimpleDateFormat;public class MainProcess {public static void main(String[] args) throws ParseException {// 1.set formatSimpleDateFormat timeSmat new SimpleDateFormat("yyyy-MM-dd HH:…

Kubernetes中安装部署ActiveMQ集群(手把手式记录)

目录 1、创建命名空间 nacos-cluster 2、配置文件准备 2.1 activemq0.xml 2.2 activemq1.xml 2.3 activemq2.xml 3、创建configMap cm-activemq 4、创建activemq-cluster.yaml 5、执行命令部署 6、部署成功&#xff0c;查看结果 这里以3个borker的集群为例&#xff0…

Facade 外观

意图 为子系统中的一组接口提供一个一致的界面&#xff0c;Facade模式定义了一个高层接口&#xff0c;这个接口使得这一字系统更加容易使用。 结构 其中&#xff1a; Facade知道哪些子系统负责处理请求&#xff1b;将客户的请求代理给适当的子系统对象。 Subsystem classes…

QGIS插件Geo-SAM使用(基于SAM半自动标注遥感图像)

0.Geo-SAM介绍 Geo-SAM是一个QGIS插件&#xff0c;旨在帮助人们在使用大尺寸地理空间栅格图像时有效地分割、描绘或标记地貌。Segment Anything Model &#xff08;SAM&#xff09; 是一个具有超能力的基础 AI 模型&#xff0c;但模型大小巨大&#xff0c;即使使用现代 GPU&am…

C++学习进阶版(一):用C++写简单的状态机实现

目录 一、基础知识 1、状态机 2、四大要素 3、描述方式 4、设计步骤 5、实现过程中需注意 &#xff08;1&#xff09; 状态定义 &#xff08;2&#xff09; 状态转换规则 &#xff08;3&#xff09; 输入处理 &#xff08;4&#xff09; 状态机的封装 &#xff08;5…

Nginx第2篇-HTTPS配置教程

背景 我最近做个项目要上线&#xff0c;接口部署到服务器&#xff0c;总不能给别人个ip地址加端口吧&#xff0c;而且小程序上线要有接口不能是ip和http协议&#xff0c;必须是https协议。这里记录下使用Nginx配置HTTPS的过程&#xff0c;主要包含以下三部分。 申请域名SSL证…

远程预付费集抄管理系统

远程预付费集抄管理系统是一种用于能源(如水、电等)预付费管理的智能化系统&#xff0c;其核心在于提供远程集中抄表和费用管理服务。这种系统通过集成先进的远程监控技术和预付费管理功能&#xff0c;为用户提供了便捷的能源管理解决方案。下文将从核心功能、工作流程、优势特…

离世界模型更近一步!Meta开源OpenEQA,评估AI Agent情景理解能力

Yann LeCun 朝着 “世界模型” 又近了一步。 Meta最新的开源工作OpenEQA&#xff1a;从文字模型到世界模型&#xff0c;可以像人一样记忆、推理的新基准&#xff0c;AI理解物理空间又近了一步。 场景1: 假设你正准备离开家&#xff0c;但找不到你的工牌。 现在&#xff0c;…