文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

HarmonyOS ArkUI之聊天列表滑动删除(TS)

2024-12-02 15:52

关注

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

简介

本项目基于ArkUI中TS扩展的声明式开发范式,关于语法和概念直接看官网官方文档地址:

基于TS扩展的声明式开发范式1基于TS扩展的声明式开发范式2

本文介绍列表滑动删除:

列表中只允许滑出其中一项

如果有打开的项,点击或滑动其他项都会关闭打开的项

点击删除,刷新列表界面

ArKUI系列文章

效果演示


主要知识点

可滑动的容器组件(Scroll)、触摸事件(onTouch)

实现思路

我把界面精简了一下,减少代码量,帮助更好的理解主要逻辑。


1、item布局

主要使用scroll包裹内容,scroll设置为横向滑动(部分代码)

  1. ..... 
  2. Scroll() { 
  3.       Row() { 
  4.         Text('内容数据'
  5.           .width('100%').height(65) 
  6.  
  7.         Button() { 
  8.           Text('删除'
  9.         } 
  10.         .width(100).height(65) 
  11.       } 
  12.  }.scrollable(ScrollDirection.Horizontal) // 设置为横向滑动 
  13. ..... 

2、Scroll容器

给Scroll容器绑定滑动组件的控制器,只用到其中的一个方法:滑动到指定位置 scrollTo

  1. scrollTo( 
  2.     value: { 
  3.     xOffset: number | string, yOffset: number | string, animation? 
  4.         : { duration: number, curve: Curve } 
  5.     } 
  6. ); 

看源码得知可以设置动画时间,注意:时间目前好像不能设置300毫秒以上,往下设置可以 (部分代码)

  1. ..... 
  2. // 初始化控制器 
  3. private scroller= new Scroller() 
  4. Scroll(scroller) { // 控制器绑定到滑动容器中 
  5.       Row() { 
  6.         Text('内容数据'
  7.           .width('100%').height(65) 
  8.  
  9.         Button() { 
  10.           Text('删除'
  11.         } 
  12.         .width(100).height(65) 
  13.       } 
  14.  }.scrollable(ScrollDirection.Horizontal) 
  15.  
  16. Button() { 
  17.   Text('点击回到原位')            
  18. }.onClick(()=>{ 
  19.   scroller.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 200, curve: Curve.Linear } }) 
  20. }) 
  21. ..... 

3、设置触摸事件

根据移动的偏移量,判断大于删除布局宽度的一半则:打开删除布局(部分代码)

  1. ..... 
  2. // 初始化控制器 
  3. private scroller= new Scroller() 
  4. // 按下的x轴坐标 
  5. private downX = 0 
  6. // 删除按钮的宽度 
  7. private deleteWidth = 100 
  8.  
  9. Scroll(scroller) { // 控制器绑定到滑动容器中 
  10.       Row() { 
  11.         Text('内容数据'
  12.           .width('100%').height(65) 
  13.  
  14.         Button() { 
  15.           Text('删除'
  16.         } 
  17.         .width(this.deleteWidth).height(65) 
  18.       } 
  19.  }.scrollable(ScrollDirection.Horizontal) 
  20. .onTouch((event: TouchEvent) => { // 触摸事件 
  21.       // 根据触摸类型判断 
  22.       switch (event.type) { 
  23.         case TouchType.Down: // 触摸按下 
  24.           // 记录按下的x轴坐标 
  25.           this.downX = event.touches[0].x 
  26.           break 
  27.         case TouchType.Up: // 触摸抬起 
  28.           // 触摸抬起,根据x轴总偏移量,判断是否打开删除 
  29.           let xOffset = event.touches[0].x - this.downX 
  30.           // 滑到目标x轴的位置 
  31.           var toxOffset = 0           
  32.           // 偏移量超过删除按钮一半且左滑,设置打开 
  33.           if (Math.abs(xOffset) > vp2px(this.deleteWidth) / 2 && xOffset < 0) { 
  34.               // 删除布局宽度 
  35.               toxOffset = vp2px(this.deleteWidth) 
  36.           } 
  37.           // 滑动指定位置,设置动画 
  38.           item.scroller.scrollTo({ xOffset: toxOffset, yOffset: 0, 
  39.             animation: { duration: 300, curve: Curve.Linear } }) 
  40.           // 重置按下的x轴坐标 
  41.           this.downX = 0 
  42.           break 
  43.       } 
  44.     }) 
  45. ..... 

4、使用列表加载

需要主要的点:

以下是完整代码,可直接粘贴运行使用。

  1. class TestData { 
  2.   content: string 
  3.   scroller: Scroller 
  4.  
  5.   constructor(content: string, scroller: Scroller) { 
  6.     this.content = content 
  7.     this.scroller = scroller 
  8.   } 
  9.  
  10. @Entry 
  11. @Component 
  12. struct SlidingDeleteList { 
  13.   // 删除按钮的宽度 
  14.   private deleteWidth = 100 
  15.   // 按下的x轴坐标 
  16.   private downX = 0 
  17.   // 已经打开删除的数据 
  18.   private openDeleteData: TestData = null 
  19.   // 测试数据 
  20.   @State private listData: Array = [ 
  21.     { content: '内容数据1', scroller: new Scroller() }, { content: '内容数据2', scroller: new Scroller() }, 
  22.     { content: '内容数据3', scroller: new Scroller() }, { content: '内容数据4', scroller: new Scroller() }, 
  23.     { content: '内容数据5', scroller: new Scroller() }, { content: '内容数据6', scroller: new Scroller() }, 
  24.     { content: '内容数据7', scroller: new Scroller() }, { content: '内容数据8', scroller: new Scroller() }, 
  25.   ] 
  26.  
  27.   @Builder CustomItem(item:TestData) { 
  28.     Scroll(item.scroller) { 
  29.       Row() { 
  30.         Text(item.content) 
  31.           .width('100%').height(65) 
  32.           .fontSize(16).textAlign(TextAlign.Center) 
  33.           .onClick(() => { 
  34.             // 如果删除按钮打开,关闭删除按钮且返回 
  35.             if (this.openDeleteData != null) { 
  36.               this.openDeleteData.scroller.scrollTo({ xOffset: 0, yOffset: 0, 
  37.                 animation: { duration: 100, curve: Curve.Linear } }) 
  38.               this.openDeleteData = null 
  39.               return 
  40.             } 
  41.             console.log('========点击内容========='
  42.           }) 
  43.  
  44.         Button() { 
  45.           Text('删除'
  46.             .fontSize(15) 
  47.             .fontColor(Color.White) 
  48.         } 
  49.         .type(ButtonType.Normal) 
  50.         .width(this.deleteWidth).height(65) 
  51.         .backgroundColor(Color.Red) 
  52.         .onClick(() => { 
  53.           // 删除当前数据 
  54.           this.listData.splice(this.listData.indexOf(item), 1) 
  55.  
  56.           // 关闭删除按钮 
  57.           if (this.openDeleteData != null) { 
  58.             this.openDeleteData.scroller.scrollTo({ xOffset: 0, yOffset: 0, 
  59.               animation: { duration: 100, curve: Curve.Linear } }) 
  60.             this.openDeleteData = null 
  61.           } 
  62.           console.log('========点击删除========='
  63.         }) 
  64.       } 
  65.     }.scrollable(ScrollDirection.Horizontal) 
  66.     .onTouch((event: TouchEvent) => { // 触摸事件 
  67.       // 判断是否有打开删除组件,有则关闭 
  68.       if (this.openDeleteData != null && this.openDeleteData != item) { 
  69.         this.openDeleteData.scroller.scrollTo({ xOffset: 0, yOffset: 0, 
  70.           animation: { duration: 100, curve: Curve.Linear } }) 
  71.       } 
  72.  
  73.       // 根据触摸类型判断 
  74.       switch (event.type) { 
  75.         case TouchType.Down: // 触摸按下 
  76.           // 记录按下的x轴坐标 
  77.           this.downX = event.touches[0].x 
  78.           break 
  79.         case TouchType.Up: // 触摸抬起 
  80.           // 触摸抬起,根据x轴总偏移量,判断是否打开删除 
  81.           let xOffset = event.touches[0].x - this.downX 
  82.           // 防止消费点击事件 
  83.           if (xOffset == 0) { 
  84.             return 
  85.           } 
  86.           // 滑到x轴的位置 
  87.           var toxOffset = 0 
  88.           // 开启删除的对象置为null 
  89.           this.openDeleteData = null
  90.           // 偏移量超过删除按钮一半且左滑,设置打开 
  91.           if (Math.abs(xOffset) > vp2px(this.deleteWidth) / 2 && xOffset < 0) { 
  92.             // 删除布局宽度 
  93.             toxOffset = vp2px(this.deleteWidth) 
  94.             this.openDeleteData = item 
  95.           } 
  96.           // 滑动指定位置,设置动画 
  97.           item.scroller.scrollTo({ xOffset: toxOffset, yOffset: 0, 
  98.             animation: { duration: 300, curve: Curve.Linear } }) 
  99.           // 重置按下的x轴坐标 
  100.           this.downX = 0 
  101.           break 
  102.       } 
  103.     }) 
  104.   } 
  105.  
  106.   build() { 
  107.     Column() { 
  108.       List() { 
  109.         ForEach(this.listData, item => { 
  110.           ListItem() { 
  111.             this.CustomItem(item) 
  112.           } 
  113.         }, item => item.toString()) 
  114.       }.divider({ color: '#f1efef', strokeWidth: 1 }) 
  115.     } 
  116.     .width('100%'
  117.     .height('100%'
  118.   } 

结尾

因为ArkUI声明式开发,是鸿蒙新出的东西,API还不是那么完善,后续跟进官网更新。以下是需要优化点:

ArkUI中的TS没有JS中的新出的插槽概念,要不然直接封装成组件,提供两个对外的接口,一个传入内容布局、一个操作布局,就像Android的组件库一样,使用者不需要知道内部实现。

每天进步一点点、需要付出努力亿点点。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

来源:鸿蒙社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯