首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

HarmonyOS鸿蒙开发实战(5.0)左右拖动切换图片效果案例实践

  • 25-03-03 06:42
  • 3663
  • 11157
blog.csdn.net

鸿蒙HarmonyOS开发实战往期必看文章:(持续更新......)

HarmonyOS NEXT应用开发性能实践总结(持续更新......)

HarmonyOS NEXT应用开发案例实践总结合集(持续更新......)

一分钟了解”纯血版!鸿蒙HarmonyOS Next应用开发!

最新版!“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线!(从零基础入门到精通)


介绍

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

效果图预览

使用说明

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

实现思路

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

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

工程结构&模块类型

  1. dragtoswitchpictures // har包
  2. |---common
  3. | |---Constants.ets // 常量类
  4. |---data
  5. | |---DragToSwitchPicturesData.ets // 生成模拟数据
  6. |---datasource
  7. | |---BasicDataSource.ets // Basic数据控制器
  8. | |---DragToSwitchPicturesDataSource.ets // 左右拖动切换图片数据控制器
  9. |---mainpage
  10. | |---DragToSwitchPictures.ets // 主页面
  11. |---model
  12. | |---DragToSwitchPicturesModule.ets // 左右拖动切换图片数据模型
  13. |---view
  14. | |---DragToSwitchPicturesView.ets // 左右拖动切换图片视图
  15. | |---DesignCattleView.ets // AI设计视图
  16. | |---TabsWaterFlowView.ets // 瀑布流嵌套Tabs视图

模块依赖

routermodule

高性能知识点

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

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

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

最后

小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)路线图、学习视频、文档用来跟着学习是非常有必要的。 

如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员

鸿蒙 NEXT 全栈开发学习笔记  希望这一份鸿蒙学习文档能够给大家带来帮助~

这份鸿蒙(HarmonyOS NEXT)包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、(南向驱动、嵌入式等)鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。


鸿蒙(HarmonyOS NEXT)最新学习路线

​

该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案

路线图适合人群:

IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术

2.视频学习教程+学习PDF文档

HarmonyOS Next 最新全套视频教程 全球开发者的开源社区,开源代码

  纯血版鸿蒙全套学习文档(面试、文档、全套视频等)  全球开发者的开源社区,开源代码

​​

《鸿蒙大厂面试真题》GitCode - 全球开发者的开源社区,开源代码

总结

参与鸿蒙开发,你要先认清适合你的方向,如果是想从事鸿蒙应用开发方向的话,可以参考本文的学习路径,简单来说就是:为了确保高效学习,建议规划清晰的学习路线

鸿蒙NEXT全套学习资料
微信名片
注:本文转载自blog.csdn.net的让开,我要吃人了的文章"https://blog.csdn.net/weixin_55362248/article/details/142523735"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top