HarmonyOS NEXT应用开发之左右拖动切换图片效果案例

介绍

本示例使用滑动手势监听,实时调整左右两侧内容显示区域大小和效果。通过绑定gesture事件中的PanGesture平移手势,实时获取拖动距离。当拖动时,实时地调节左右两个Image组件的宽度,从而成功实现左右拖动切换图片效果的功能。

效果图预览

使用说明

  1. 点击中间按钮进行左右拖动切换图片。

实现思路

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

  1. 创建三个Stack组件,用来展示装修前后对比图,第一个和第三个Stack分别存放装修前的图片和装修后的图片,zIndex设置为1。第二个Stack存放按钮的图片,zIndex设置为2,这样按钮的图片就会覆盖在两张装修图片之上。 源码参考DragToSwitchPicturesView.ets。
Row() {Stack() {...}.zIndex(CONFIGURATION.ZINDEX1).width(this.leftImageWidth) // z序设为1,为了使按钮图片浮在装修图片上。Stack() {...}.width($r('app.integer.drag_button_stack_width')).zIndex(CONFIGURATION.ZINDEX2) // z序设为2,为了使按钮图片浮在装修图片上。Stack() {...}.zIndex(CONFIGURATION.ZINDEX1) // z序设为1,为了使按钮图片浮在装修图片上。.width(this.rightImageWidth)
}
.justifyContent(FlexAlign.Center)
.width($r('app.string.full_size'))
  1. 将Image组件放在Row容器里,将Row容器的宽度设置为状态变量,再利用clip属性对于Row容器进行裁剪。 源码参考DragToSwitchPicturesView.ets。
Row() {Image($r('app.media.before_decoration')).width($r('app.integer.decoration_width'))// Image的width固定,Row的宽度变化,通过裁剪实现布局效果。.height($r('app.integer.decoration_height')).draggable(false) // 设置Image不能拖动,不然长按Image会被拖动。}.width(this.leftImageWidth) // 将左侧Row的width设置为leftImageWidth,这样左侧Row的width随leftImageWidth的变化而变化。.clip(true) // clip属性设置为true,裁剪超出Row宽度的图片。.zIndex(CONFIGURATION.ZINDEX1) // z序设为1,为了使水印浮在装修图片上。.borderRadius({topLeft: $r('app.integer.borderradius'),bottomLeft: $r('app.integer.borderradius')}) // 将Row的左上角和左下角弧度设为10实现效果。
  1. 右边的Image组件与左边同样的操作,但是新增了一个direction属性,使元素从右至左进行布局,为的是让Row从左侧开始裁剪。 源码参考DragToSwitchPicturesView.ets。
Row() {Image($r('app.media.after_decoration')).width($r('app.integer.decoration_width')).height($r('app.integer.decoration_height')).draggable(false)
}
.width(this.rightImageWidth)
.clip(true)
.zIndex(CONFIGURATION.ZINDEX1) // z序设为1,为了使水印浮在装修图片上。
// TODO: 知识点:左边Row使用clip时从右边开始裁剪,加了Direction.Rtl后,元素从右到左布局,右边Row使用clip时从左边开始裁剪,这是实现滑动改变视图内容大小的关键。
.direction(Direction.Rtl)
.borderRadius({topRight: $r('app.integer.borderradius'),bottomRight: $r('app.integer.borderradius')
}) // 将Row的右上角和右下角弧度设为10实现效果。
  1. 中间的Image组件通过手势事件中的滑动手势对Image组件滑动进行监听,对左右Image组件的宽度进行计算从而重新布局渲染。 源码参考DragToSwitchPicturesView.ets。
Image($r('app.media.drag_button')).width($r('app.integer.drag_button_image_width')).height($r('app.integer.decoration_height')).draggable(false).gesture( // TODO: 知识点:拖动手势事件设置一个手指,滑动的最小距离设置为1vp,实现滑动时按钮跟手动效。PanGesture({ fingers: CONFIGURATION.PANGESTURE_FINGERS, distance: CONFIGURATION.PANGESTURE_DISTANCE }).onActionStart(() => {this.dragRefOffset = CONFIGURATION.INIT_VALUE; // 每次拖动开始时将图标拖动的距离初始化。})// TODO: 性能知识点: 该函数是系统高频回调函数,避免在函数中进行冗余或耗时操作,例如应该减少或避免在函数打印日志,会有较大的性能损耗。.onActionUpdate((event: GestureEvent) => {// 通过监听GestureEvent事件,实时监听图标拖动距离this.dragRefOffset = event.offsetX;this.leftImageWidth = this.imageWidth + this.dragRefOffset;this.rightImageWidth = CONFIGURATION.IMAGE_FULL_SIZE - this.leftImageWidth;if (this.leftImageWidth >= CONFIGURATION.LEFT_IMAGE_RIGHT_LIMIT_SIZE) { // 当leftImageWidth大于等于310vp时,设置左右Image为固定值,实现停止滑动效果。this.leftImageWidth = CONFIGURATION.LEFT_IMAGE_RIGHT_LIMIT_SIZE;this.rightImageWidth = CONFIGURATION.RIGHT_IMAGE_RIGHT_LIMIT_SIZE;} else if (this.leftImageWidth <= CONFIGURATION.LEFT_IMAGE_LEFT_LIMIT_SIZE) { // 当leftImageWidth小于等于30vp时,设置左右Image为固定值,实现停止滑动效果。this.leftImageWidth = CONFIGURATION.LEFT_IMAGE_LEFT_LIMIT_SIZE;this.rightImageWidth = CONFIGURATION.RIGHT_IMAGE_LEFT_LIMIT_SIZE;}}).onActionEnd((event: GestureEvent) => {if (this.leftImageWidth <= CONFIGURATION.LEFT_IMAGE_LEFT_LIMIT_SIZE) {this.leftImageWidth = CONFIGURATION.LEFT_IMAGE_LEFT_LIMIT_SIZE;this.rightImageWidth = CONFIGURATION.RIGHT_IMAGE_LEFT_LIMIT_SIZE;this.imageWidth = CONFIGURATION.LEFT_IMAGE_LEFT_LIMIT_SIZE;} else if (this.leftImageWidth >= CONFIGURATION.LEFT_IMAGE_RIGHT_LIMIT_SIZE) {this.leftImageWidth = CONFIGURATION.LEFT_IMAGE_RIGHT_LIMIT_SIZE;this.rightImageWidth = CONFIGURATION.RIGHT_IMAGE_RIGHT_LIMIT_SIZE;this.imageWidth = CONFIGURATION.LEFT_IMAGE_RIGHT_LIMIT_SIZE;} else {this.leftImageWidth = this.imageWidth + this.dragRefOffset; // 滑动结束时leftImageWidth等于左边原有Width+拖动距离。this.rightImageWidth = CONFIGURATION.IMAGE_FULL_SIZE - this.leftImageWidth; // 滑动结束时rightImageWidth等于340-leftImageWidth。this.imageWidth = this.leftImageWidth; // 滑动结束时ImageWidth等于leftImageWidth。}}))

工程结构&模块类型

   dragtoswitchpictures                             // har包|---common|   |---Constants.ets                            // 常量类|---data|   |---DragToSwitchPicturesData.ets             // 生成模拟数据|---datasource|   |---BasicDataSource.ets                      // Basic数据控制器|   |---DragToSwitchPicturesDataSource.ets       // 左右拖动切换图片数据控制器|---mainpage|   |---DragToSwitchPictures.ets                 // 主页面|---model|   |---DragToSwitchPicturesModule.ets           // 左右拖动切换图片数据模型|---view|   |---DragToSwitchPicturesView.ets             // 左右拖动切换图片视图|   |---DesignCattleView.ets                     // AI设计视图|   |---TabsWaterFlowView.ets                    // 瀑布流嵌套Tabs视图

模块依赖

routermodule

高性能知识点

本例使用了onActionUpdate函数。该函数是系统高频回调函数,避免在函数中进行冗余或耗时操作,例如应该减少或避免在函数打印日志,会有较大的性能损耗。

本示例使用了LazyForEach进行数据懒加载,WaterFlow布局时会根据可视区域按需创建FlowItem组件,并在FlowItem滑出可视区域外时销毁以降低内存占用。

本示例使用了cachedCount设置预加载的FlowItem的数量,只在LazyForEach中生效,设置该属性后会缓存cachedCount个FlowItem,LazyForEach超出显示和缓存范围的FlowItem会被释放。

参考资料

LazyForEach:数据懒加载

Tabs

WaterFlow

ZIndex

PanGesture

clip

direction

为了能让大家更好的学习鸿蒙(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.鸿蒙南向开发方向

腾讯T10级高工技术,安卓全套VIP课程全网免费送:https://qr21.cn/D2k9D5

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

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

相关文章

强森算法求两点最短路径的基本流程及代码实现

对于强森算法,给定的一个图中,算法首先会构造一个新的节点s,然后从新构造的这个节点引出多条边分别连通图中的每一个节点,这些边的长度一开始是被设置为0的,然后使用贝尔曼-福德算法进行计算,算出从s到图中每一个节点的最短路径。 而在运行贝尔曼-福德算法的过程中如果发…

机器学习之无监督学习简介及算法库推荐

文章目录 无监督学习概述无监督学习定义无监督学习与有监督学习的区别 算法库推荐无监督学习的主要算法聚类算法K-means算法 降维算法PCA算法 聚类算法详解K-means算法算法步骤&#xff1a; DBSCAN算法算法步骤&#xff1a; 降维算法详解主成分分析(PCA)原理代码示例 t-SNE算法…

C语言之动态内存管理(快点进来!!!)

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

2024全国水科技大会【联合主办】福州水务集团有限公司

福州水务成立于2008年11月&#xff0c;AA信用评级&#xff0c;注册资本21.2亿元。下属各级企业70多家&#xff08;包括3家国家级高新技术企业、1家A股上市企业&#xff09;。集团主营供水、排水、环保、温泉文旅、综合服务五大板块&#xff0c;旗下运营自来水厂17座&#xff0c…

【WSL】Ubuntu 20.04 字符集不认识中文,及其中文路径

1. 问题 $ locale locale: Cannot set LC_CTYPE to default locale: No such file or directory locale: Cannot set LC_ALL to default locale: No such file or directory LANGen_US.UTF-8 LANGUAGE LC_CTYPEUTF-8 LC_NUMERIC"en_US.UTF-8" LC_TIME"en_US.UT…

算法沉淀——贪心算法五(leetcode真题剖析)

算法沉淀——贪心算法五 01.跳跃游戏 II02.跳跃游戏03.加油站04.单调递增的数字 01.跳跃游戏 II 题目链接&#xff1a;https://leetcode.cn/problems/jump-game-ii/ 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转…

redis在springboot项目中的应用

一&#xff0c;将查询结果放到redis中作为缓存&#xff0c;减轻mysql的压力。 只有在数据量大的时候&#xff0c;查询速度慢的时候才有意义。 本次测试的数据量为XXX. 测试代码: 功能为根据昵称进行模糊匹配。 GetMapping("/get-by-nick")public String getNickN…

维度建模理论之事实表

事实表概述 事实表作为数据仓库维度建模的核心&#xff0c;紧紧围绕着业务过程来设计。其包含与该业务过程有关的维度引用&#xff08;维度表外键&#xff09;以及该业务过程的度量&#xff08;通常是可累加的数字类型字段&#xff09;。 事实表特点 事实表通常比较“细长”…

Node.js核心命令与工具:提升开发效率的实用指南

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

Redis面试题以及答案

1. 什么是Redis&#xff1f;它主要用来什么的&#xff1f; Redis&#xff0c;英文全称是Remote Dictionary Server&#xff08;远程字典服务&#xff09;&#xff0c;是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并…

Python基础入门 --- 7.函数

Python基础入门 第七章&#xff1a; 7.函数 7.1 函数多返回值 按照返回值顺序&#xff0c;写对应顺序的多个变量接收&#xff0c;变量之间用逗号分隔&#xff0c;支持不同数据类型return def test_return():return 1,"hello", Truex, y, z test_return() print…

刷力扣看见一个寻找单身狗的问题?【力扣题解】

今天刷力扣遇到一道有意思的题目&#xff0c;题目是写着撞色问题177 &#xff0c;当我写完这个题去看看有什么好的解题方式的时候&#xff0c;看见一个有趣的题解问题&#xff0c;他对这个题目的描述是几对情侣&#xff0c;带几个单身狗出去玩&#xff0c;然后现在我们要把这几…

天文馆3D可视化:揭秘宇宙星辰的奇幻之旅

在这个科技日新月异的时代&#xff0c;我们似乎离神秘的宇宙越来越近。 天文馆作为普及天文知识、展示宇宙奥秘的重要场所&#xff0c;一直备受人们的喜爱。然而&#xff0c;传统的天文馆展示方式往往局限于平面图片和简单的模型&#xff0c;无法让人真正感受到宇宙的浩瀚与壮丽…

[Java安全入门]五.CC3

一.前言 前几天学了一下cc1和cc6&#xff0c;对于我来说有点小困难&#xff0c;不过经过几天沉淀&#xff0c;现在也是如拨开云雾见青天&#xff0c;经过一上午的复习对cc1和cc6又有深入的了解。所以&#xff0c;今天想多学一下cc3。cc3执行命令的方式与cc1和cc6不一样&#x…

Linux: boot: latency启动延迟分析

https://elinux.org/images/6/64/Chris-simmonds-boot-time-elce-2017_0.pdf https://www.hcltech.com/sites/default/files/documents/resources/whitepaper/files/an_insight_to_optimize_embedded_linux_boot_time_performance.pdf 无意看到这个启动延迟分析&#xff0c;虽…

Java与Go:指针

在计算机内存中&#xff0c;每个变量都有一个唯一的地址&#xff0c;指针就是用来保存这个地址的变量。通过指针&#xff0c;我们可以间接地访问和修改存储在该地址处的数据。今天我们来聊一聊Java和Go指针&#xff0c;预告一下&#xff0c;我们需要借助C语言做一些小小的比较。…

Redis的五种数据类型与常用命令示例

Redis的五种数据类型 String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Set&#xff08;集合&#xff09;、Hash&#xff08;哈希&#xff09;和Zset&#xff08;有序集合&#xff09;&#xff0c;每种数据类型都有一些常用的操作命令。 1、String类…

【堆】Top-K问题

标题&#xff1a;C语言库函数scanf&#xff08;&#xff09;解读 水墨不写bug &#xff08;图片来源于网络&#xff09; 正文开始&#xff1a; Top-K问题是一类问题的统称&#xff1a; 即根据对象的某一属性&#xff0c;找出这个属性最突出的K个对象&#xff0c;并且通常对象…

专升本 C语言笔记-10 指针数组 和 数组指针

一、数组 和 指针 的区别 数组和指针的介绍1、指针是一个变量&#xff0c;它存储了一个内存地址&#xff0c;该地址指向一个变量的存储位置。2、通过指针&#xff0c;可以访问和修改指向的变量。3、数组是一个由相同数据类型元素组成的集合&#xff0c;可以通过索引来访问和修改…

Linux-网络基础-套接字详细过程

目录 一、数据传输IP地址端口协议网络字节序网络通信--五元组 二、socket套接字1、udp、tcp区别2、套接字接口&#xff08;udp通信程序&#xff09;通信流程&#xff1a;接口代码&#xff08;udp&#xff09; 3、套接字接口&#xff08;tcp通信程序&#xff09;通信流程&#x…