首页 / 行业
如何在鸿蒙上实现聊天列表滑动删除功能
2021-12-03 10:55:00
本项目基于 ArkUI 中 TS 扩展的声明式开发范式,关于语法和概念直接看官网。
基于 TS 扩展的声明式开发范式 1:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-ts-overview-0000001192705715
基于 TS 扩展的声明式开发范式 2:https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-framework-directory-0000001111581264
本文介绍列表滑动删除:
列表中只允许滑出其中一项
如果有打开的项,点击或滑动其他项都会关闭打开的项
点击删除,刷新列表界面
主要知识点
可滑动的容器组件(Scroll):
https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-container-scroll-0000001163543527
触摸事件(onTouch):
https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-universal-events-touch-0000001158261221
实现思路
我把界面精简了一下,减少代码量,帮助更好的理解主要逻辑。
①item 布局主要使用 scroll 包裹内容,scroll 设置为横向滑动。部分代码如下:.....Scroll(){Row(){Text('内容数据').width('100%').height(65)Button(){Text('删除')}.width(100).height(65)}}.scrollable(ScrollDirection.Horizontal)//设置为横向滑动.....
②Scroll 容器给 Scroll 容器绑定滑动组件的控制器,只用到其中的一个方法:滑动到指定位置 scrollTo。
scrollTo(value:{xOffset:number|string,yOffset:number|string,animation?:{duration:number,curve:Curve}});
看源码得知可以设置动画时间,注意:时间目前好像不能设置 300 毫秒以上,往下设置可以。部分代码如下:
.....//初始化控制器privatescroller=newScroller()Scroll(scroller){//控制器绑定到滑动容器中Row(){Text('内容数据').width('100%').height(65)Button(){Text('删除')}.width(100).height(65)}}.scrollable(ScrollDirection.Horizontal)Button(){Text('点击回到原位')}.onClick(()=>{scroller.scrollTo({xOffset:0,yOffset:0,animation:{duration:200,curve:Curve.Linear}})}).....
③设置触摸事件根据移动的偏移量,判断大于删除布局宽度的一半则:打开删除布局。部分代码如下:
.....//初始化控制器privatescroller=newScroller()//按下的x轴坐标privatedownX=0//删除按钮的宽度privatedeleteWidth=100Scroll(scroller){//控制器绑定到滑动容器中Row(){Text('内容数据').width('100%').height(65)Button(){Text('删除')}.width(this.deleteWidth).height(65)}}.scrollable(ScrollDirection.Horizontal).onTouch((event:TouchEvent)=>{//触摸事件//根据触摸类型判断switch(event.type){caseTouchType.Down://触摸按下//记录按下的x轴坐标this.downX=event.touches[0].xbreakcaseTouchType.Up://触摸抬起//触摸抬起,根据x轴总偏移量,判断是否打开删除letxOffset=event.touches[0].x-this.downX//滑到目标x轴的位置vartoxOffset=0//偏移量超过删除按钮一半且左滑,设置打开if(Math.abs(xOffset)>vp2px(this.deleteWidth)/2&&xOffset< 0){//删除布局宽度toxOffset=vp2px(this.deleteWidth)}//滑动指定位置,设置动画item.scroller.scrollTo({xOffset:toxOffset,yOffset:0,animation:{duration:300,curve:Curve.Linear}})//重置按下的x轴坐标this.downX=0break}}).....
④使用列表加载需要主要的点:需要给每个 item 绑定控制器,这样才能控制对应的 item 打开或关闭
打开的 item 记录一下数据,点击内容或删除、滑动其他 item:如果有带打开的 item,进行关闭
以下是完整代码,可直接粘贴运行使用:
classTestData{content:stringscroller:Scrollerconstructor(content:string,scroller:Scroller){this.content=contentthis.scroller=scroller}}@Entry@ComponentstructSlidingDeleteList{//删除按钮的宽度privatedeleteWidth=100//按下的x轴坐标privatedownX=0//已经打开删除的数据privateopenDeleteData:TestData=null//测试数据@StateprivatelistData:Array=[{content:'内容数据1',scroller:newScroller()},{content:'内容数据2',scroller:newScroller()},{content:'内容数据3',scroller:newScroller()},{content:'内容数据4',scroller:newScroller()},{content:'内容数据5',scroller:newScroller()},{content:'内容数据6',scroller:newScroller()},{content:'内容数据7',scroller:newScroller()},{content:'内容数据8',scroller:newScroller()},]@BuilderCustomItem(item:TestData){Scroll(item.scroller){Row(){Text(item.content).width('100%').height(65).fontSize(16).textAlign(TextAlign.Center).onClick(()=>{//如果删除按钮打开,关闭删除按钮且返回if(this.openDeleteData!=null){this.openDeleteData.scroller.scrollTo({xOffset:0,yOffset:0,animation:{duration:100,curve:Curve.Linear}})this.openDeleteData=nullreturn}console.log('========点击内容=========')})Button(){Text('删除').fontSize(15).fontColor(Color.White)}.type(ButtonType.Normal).width(this.deleteWidth).height(65).backgroundColor(Color.Red).onClick(()=>{//删除当前数据this.listData.splice(this.listData.indexOf(item),1)//关闭删除按钮if(this.openDeleteData!=null){this.openDeleteData.scroller.scrollTo({xOffset:0,yOffset:0,animation:{duration:100,curve:Curve.Linear}})this.openDeleteData=null}console.log('========点击删除=========')})}}.scrollable(ScrollDirection.Horizontal).onTouch((event:TouchEvent)=>{//触摸事件//判断是否有打开删除组件,有则关闭if(this.openDeleteData!=null&&this.openDeleteData!=item){this.openDeleteData.scroller.scrollTo({xOffset:0,yOffset:0,animation:{duration:100,curve:Curve.Linear}})}//根据触摸类型判断switch(event.type){caseTouchType.Down://触摸按下//记录按下的x轴坐标this.downX=event.touches[0].xbreakcaseTouchType.Up://触摸抬起//触摸抬起,根据x轴总偏移量,判断是否打开删除letxOffset=event.touches[0].x-this.downX//防止消费点击事件if(xOffset==0){return}//滑到x轴的位置vartoxOffset=0//开启删除的对象置为nullthis.openDeleteData=null;//偏移量超过删除按钮一半且左滑,设置打开if(Math.abs(xOffset)>vp2px(this.deleteWidth)/2&&xOffset< 0){//删除布局宽度toxOffset=vp2px(this.deleteWidth)this.openDeleteData=item}//滑动指定位置,设置动画item.scroller.scrollTo({xOffset:toxOffset,yOffset:0,animation:{duration:300,curve:Curve.Linear}})//重置按下的x轴坐标this.downX=0break}})}build(){Column(){List(){ForEach(this.listData,item=>{ListItem(){this.CustomItem(item)}},item=>item.toString())}.divider({color:'#f1efef',strokeWidth:1})}.width('100%').height('100%')}}
结尾
因为 ArkUI 声明式开发,是鸿蒙新出的东西,API 还不是那么完善,后续跟进官网更新。以下是需要优化点:ArkUI 中的 TS 没有 JS 中的新出的插槽概念,要不然直接封装成组件,提供两个对外的接口,一个传入内容布局、一个操作布局,就像 Android 的组件库一样,使用者不需要知道内部实现。作者:梁青松编辑:jq最新内容
手机 |
相关内容
英伟达芯片开发过程引入聊天机器人
英伟达芯片开发过程引入聊天机器人,扩展更多AI应用,聊天机器人,扩展,芯片,英伟达,开发过程,调试,英伟达是一家全球领先的半导体公司,什么是扩展器,扩展器的组成、特点、
什么是扩展器,扩展器的组成、特点、原理、分类、操作规程及发展趋势,扩展器,发展趋势,分类,用于,扩张,状态,TNY266PN扩展器是一种用芯片粘接失效模式和芯片粘接强度提
芯片粘接失效模式和芯片粘接强度提高途径,芯片,模式,失效,控制,界面,导致,芯片粘接是将两个芯片或其他材料通过粘接剂粘接在一起的NVIDIA 扩展机器人平台,迎接生成式
NVIDIA 扩展机器人平台,迎接生成式 AI 的崛起,崛起,生成式,平台,扩展,人工智能,智能,近年来,人工智能(Artificial Intelligence,AI)技术七腾机器人亮相世界石油天然气装备
七腾机器人亮相世界石油天然气装备博览会,加快实现国内防爆四足产品落地,国内,产品,可扩展性,行业,需求,支持,近年来,随着石油天然气TDK机器学习解决方案促进边缘人工
TDK机器学习解决方案促进边缘人工智能前景大幅扩展,解决方案,前景,边缘,人工智能,机器学习,扩展,随着人工智能的不断发展,边缘计算作台积电报明牌:硅光子将成半导体产业
台积电报明牌:硅光子将成半导体产业关键技术,台积电,云计算,芯片,光纤,可扩展性,器件,硅光子技术是一种将光子和电子相结合的技术,通三星电子推出首个LPCAMM内存解决方
三星电子推出首个LPCAMM内存解决方案,内存,推出,解决方案,内存模块,数据,可扩展性,三星电子日前宣布推出其首个LPCAMM(Low Power Cac